mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 09:09:09 +02:00
* move constant folding into det_resulttype
This commit is contained in:
parent
226ea788db
commit
759f678192
@ -76,10 +76,20 @@ implementation
|
|||||||
|
|
||||||
function taddnode.det_resulttype:tnode;
|
function taddnode.det_resulttype:tnode;
|
||||||
var
|
var
|
||||||
hp : tnode;
|
hp,t : tnode;
|
||||||
lt,rt : tnodetype;
|
lt,rt : tnodetype;
|
||||||
rd,ld : pdef;
|
rd,ld : pdef;
|
||||||
htype : ttype;
|
htype : ttype;
|
||||||
|
ot : tnodetype;
|
||||||
|
concatstrings : boolean;
|
||||||
|
resultset : pconstset;
|
||||||
|
i : longint;
|
||||||
|
b : boolean;
|
||||||
|
s1,s2 : pchar;
|
||||||
|
l1,l2 : longint;
|
||||||
|
rv,lv : tconstexprint;
|
||||||
|
rvd,lvd : bestreal;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
|
|
||||||
@ -113,6 +123,310 @@ implementation
|
|||||||
rd:=right.resulttype.def;
|
rd:=right.resulttype.def;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ both are int constants }
|
||||||
|
if (((is_constintnode(left) and is_constintnode(right)) or
|
||||||
|
(is_constboolnode(left) and is_constboolnode(right) and
|
||||||
|
(nodetype in [ltn,lten,gtn,gten,equaln,unequaln,andn,xorn,orn])))) or
|
||||||
|
{ support pointer arithmetics on constants (JM) }
|
||||||
|
((lt = pointerconstn) and is_constintnode(right) and
|
||||||
|
(nodetype in [addn,subn])) or
|
||||||
|
((lt = pointerconstn) and (rt = pointerconstn) and
|
||||||
|
(nodetype in [ltn,lten,gtn,gten,equaln,unequaln,subn])) then
|
||||||
|
begin
|
||||||
|
{ when comparing/substracting pointers, make sure they are }
|
||||||
|
{ of the same type (JM) }
|
||||||
|
if (lt = pointerconstn) and (rt = pointerconstn) then
|
||||||
|
begin
|
||||||
|
if not(cs_extsyntax in aktmoduleswitches) and
|
||||||
|
not(nodetype in [equaln,unequaln]) then
|
||||||
|
CGMessage(type_e_mismatch)
|
||||||
|
else
|
||||||
|
if (nodetype <> subn) and
|
||||||
|
is_voidpointer(rd) then
|
||||||
|
inserttypeconv(right,left.resulttype)
|
||||||
|
else if (nodetype <> subn) and
|
||||||
|
is_voidpointer(ld) then
|
||||||
|
inserttypeconv(left,right.resulttype)
|
||||||
|
else if not(is_equal(ld,rd)) then
|
||||||
|
CGMessage(type_e_mismatch);
|
||||||
|
end
|
||||||
|
else if (lt=ordconstn) and (rt=ordconstn) then
|
||||||
|
begin
|
||||||
|
{ make left const type the biggest, this type will be used
|
||||||
|
for orn,andn,xorn }
|
||||||
|
if rd^.size>ld^.size then
|
||||||
|
inserttypeconv(left,right.resulttype);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ load values }
|
||||||
|
if (lt = ordconstn) then
|
||||||
|
lv:=tordconstnode(left).value
|
||||||
|
else
|
||||||
|
lv:=tpointerconstnode(left).value;
|
||||||
|
if (rt = ordconstn) then
|
||||||
|
rv:=tordconstnode(right).value
|
||||||
|
else
|
||||||
|
rv:=tpointerconstnode(right).value;
|
||||||
|
if (lt = pointerconstn) and
|
||||||
|
(rt <> pointerconstn) then
|
||||||
|
rv := rv * ppointerdef(left.resulttype.def)^.pointertype.def^.size;
|
||||||
|
if (rt = pointerconstn) and
|
||||||
|
(lt <> pointerconstn) then
|
||||||
|
lv := lv * ppointerdef(right.resulttype.def)^.pointertype.def^.size;
|
||||||
|
case nodetype of
|
||||||
|
addn :
|
||||||
|
if (lt <> pointerconstn) then
|
||||||
|
t := genintconstnode(lv+rv)
|
||||||
|
else
|
||||||
|
t := cpointerconstnode.create(lv+rv,left.resulttype);
|
||||||
|
subn :
|
||||||
|
if (lt <> pointerconstn) or (rt = pointerconstn) then
|
||||||
|
t := genintconstnode(lv-rv)
|
||||||
|
else
|
||||||
|
t := cpointerconstnode.create(lv-rv,left.resulttype);
|
||||||
|
muln :
|
||||||
|
t:=genintconstnode(lv*rv);
|
||||||
|
xorn :
|
||||||
|
t:=cordconstnode.create(lv xor rv,left.resulttype);
|
||||||
|
orn :
|
||||||
|
t:=cordconstnode.create(lv or rv,left.resulttype);
|
||||||
|
andn :
|
||||||
|
t:=cordconstnode.create(lv and rv,left.resulttype);
|
||||||
|
ltn :
|
||||||
|
t:=cordconstnode.create(ord(lv<rv),booltype);
|
||||||
|
lten :
|
||||||
|
t:=cordconstnode.create(ord(lv<=rv),booltype);
|
||||||
|
gtn :
|
||||||
|
t:=cordconstnode.create(ord(lv>rv),booltype);
|
||||||
|
gten :
|
||||||
|
t:=cordconstnode.create(ord(lv>=rv),booltype);
|
||||||
|
equaln :
|
||||||
|
t:=cordconstnode.create(ord(lv=rv),booltype);
|
||||||
|
unequaln :
|
||||||
|
t:=cordconstnode.create(ord(lv<>rv),booltype);
|
||||||
|
slashn :
|
||||||
|
begin
|
||||||
|
{ int/int becomes a real }
|
||||||
|
if int(rv)=0 then
|
||||||
|
begin
|
||||||
|
Message(parser_e_invalid_float_operation);
|
||||||
|
t:=crealconstnode.create(0,pbestrealtype^);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
t:=crealconstnode.create(int(lv)/int(rv),pbestrealtype^);
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
CGMessage(type_e_mismatch);
|
||||||
|
end;
|
||||||
|
resulttypepass(t);
|
||||||
|
result:=t;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ both real constants ? }
|
||||||
|
if (lt=realconstn) and (rt=realconstn) then
|
||||||
|
begin
|
||||||
|
lvd:=trealconstnode(left).value_real;
|
||||||
|
rvd:=trealconstnode(right).value_real;
|
||||||
|
case nodetype of
|
||||||
|
addn :
|
||||||
|
t:=crealconstnode.create(lvd+rvd,pbestrealtype^);
|
||||||
|
subn :
|
||||||
|
t:=crealconstnode.create(lvd-rvd,pbestrealtype^);
|
||||||
|
muln :
|
||||||
|
t:=crealconstnode.create(lvd*rvd,pbestrealtype^);
|
||||||
|
starstarn,
|
||||||
|
caretn :
|
||||||
|
begin
|
||||||
|
if lvd<0 then
|
||||||
|
begin
|
||||||
|
Message(parser_e_invalid_float_operation);
|
||||||
|
t:=crealconstnode.create(0,pbestrealtype^);
|
||||||
|
end
|
||||||
|
else if lvd=0 then
|
||||||
|
t:=crealconstnode.create(1.0,pbestrealtype^)
|
||||||
|
else
|
||||||
|
t:=crealconstnode.create(exp(ln(lvd)*rvd),pbestrealtype^);
|
||||||
|
end;
|
||||||
|
slashn :
|
||||||
|
begin
|
||||||
|
if rvd=0 then
|
||||||
|
begin
|
||||||
|
Message(parser_e_invalid_float_operation);
|
||||||
|
t:=crealconstnode.create(0,pbestrealtype^);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
t:=crealconstnode.create(lvd/rvd,pbestrealtype^);
|
||||||
|
end;
|
||||||
|
ltn :
|
||||||
|
t:=cordconstnode.create(ord(lvd<rvd),booltype);
|
||||||
|
lten :
|
||||||
|
t:=cordconstnode.create(ord(lvd<=rvd),booltype);
|
||||||
|
gtn :
|
||||||
|
t:=cordconstnode.create(ord(lvd>rvd),booltype);
|
||||||
|
gten :
|
||||||
|
t:=cordconstnode.create(ord(lvd>=rvd),booltype);
|
||||||
|
equaln :
|
||||||
|
t:=cordconstnode.create(ord(lvd=rvd),booltype);
|
||||||
|
unequaln :
|
||||||
|
t:=cordconstnode.create(ord(lvd<>rvd),booltype);
|
||||||
|
else
|
||||||
|
CGMessage(type_e_mismatch);
|
||||||
|
end;
|
||||||
|
resulttypepass(t);
|
||||||
|
result:=t;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ concating strings ? }
|
||||||
|
concatstrings:=false;
|
||||||
|
s1:=nil;
|
||||||
|
s2:=nil;
|
||||||
|
if (lt=ordconstn) and (rt=ordconstn) and
|
||||||
|
is_char(ld) and is_char(rd) then
|
||||||
|
begin
|
||||||
|
s1:=strpnew(char(byte(tordconstnode(left).value)));
|
||||||
|
s2:=strpnew(char(byte(tordconstnode(right).value)));
|
||||||
|
l1:=1;
|
||||||
|
l2:=1;
|
||||||
|
concatstrings:=true;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (lt=stringconstn) and (rt=ordconstn) and is_char(rd) then
|
||||||
|
begin
|
||||||
|
s1:=tstringconstnode(left).getpcharcopy;
|
||||||
|
l1:=tstringconstnode(left).len;
|
||||||
|
s2:=strpnew(char(byte(tordconstnode(right).value)));
|
||||||
|
l2:=1;
|
||||||
|
concatstrings:=true;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (lt=ordconstn) and (rt=stringconstn) and is_char(ld) then
|
||||||
|
begin
|
||||||
|
s1:=strpnew(char(byte(tordconstnode(left).value)));
|
||||||
|
l1:=1;
|
||||||
|
s2:=tstringconstnode(right).getpcharcopy;
|
||||||
|
l2:=tstringconstnode(right).len;
|
||||||
|
concatstrings:=true;
|
||||||
|
end
|
||||||
|
else if (lt=stringconstn) and (rt=stringconstn) then
|
||||||
|
begin
|
||||||
|
s1:=tstringconstnode(left).getpcharcopy;
|
||||||
|
l1:=tstringconstnode(left).len;
|
||||||
|
s2:=tstringconstnode(right).getpcharcopy;
|
||||||
|
l2:=tstringconstnode(right).len;
|
||||||
|
concatstrings:=true;
|
||||||
|
end;
|
||||||
|
if concatstrings then
|
||||||
|
begin
|
||||||
|
case nodetype of
|
||||||
|
addn :
|
||||||
|
t:=cstringconstnode.createpchar(concatansistrings(s1,s2,l1,l2),l1+l2);
|
||||||
|
ltn :
|
||||||
|
t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)<0),booltype);
|
||||||
|
lten :
|
||||||
|
t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)<=0),booltype);
|
||||||
|
gtn :
|
||||||
|
t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)>0),booltype);
|
||||||
|
gten :
|
||||||
|
t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)>=0),booltype);
|
||||||
|
equaln :
|
||||||
|
t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)=0),booltype);
|
||||||
|
unequaln :
|
||||||
|
t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)<>0),booltype);
|
||||||
|
end;
|
||||||
|
ansistringdispose(s1,l1);
|
||||||
|
ansistringdispose(s2,l2);
|
||||||
|
resulttypepass(t);
|
||||||
|
result:=t;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ set constant evaluation }
|
||||||
|
if (right.nodetype=setconstn) and
|
||||||
|
not assigned(tsetconstnode(right).left) and
|
||||||
|
(left.nodetype=setconstn) and
|
||||||
|
not assigned(tsetconstnode(left).left) then
|
||||||
|
begin
|
||||||
|
new(resultset);
|
||||||
|
case nodetype of
|
||||||
|
addn :
|
||||||
|
begin
|
||||||
|
for i:=0 to 31 do
|
||||||
|
resultset^[i]:=tsetconstnode(right).value_set^[i] or tsetconstnode(left).value_set^[i];
|
||||||
|
t:=csetconstnode.create(resultset,left.resulttype);
|
||||||
|
end;
|
||||||
|
muln :
|
||||||
|
begin
|
||||||
|
for i:=0 to 31 do
|
||||||
|
resultset^[i]:=tsetconstnode(right).value_set^[i] and tsetconstnode(left).value_set^[i];
|
||||||
|
t:=csetconstnode.create(resultset,left.resulttype);
|
||||||
|
end;
|
||||||
|
subn :
|
||||||
|
begin
|
||||||
|
for i:=0 to 31 do
|
||||||
|
resultset^[i]:=tsetconstnode(left).value_set^[i] and not(tsetconstnode(right).value_set^[i]);
|
||||||
|
t:=csetconstnode.create(resultset,left.resulttype);
|
||||||
|
end;
|
||||||
|
symdifn :
|
||||||
|
begin
|
||||||
|
for i:=0 to 31 do
|
||||||
|
resultset^[i]:=tsetconstnode(left).value_set^[i] xor tsetconstnode(right).value_set^[i];
|
||||||
|
t:=csetconstnode.create(resultset,left.resulttype);
|
||||||
|
end;
|
||||||
|
unequaln :
|
||||||
|
begin
|
||||||
|
b:=true;
|
||||||
|
for i:=0 to 31 do
|
||||||
|
if tsetconstnode(right).value_set^[i]=tsetconstnode(left).value_set^[i] then
|
||||||
|
begin
|
||||||
|
b:=false;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
t:=cordconstnode.create(ord(b),booltype);
|
||||||
|
end;
|
||||||
|
equaln :
|
||||||
|
begin
|
||||||
|
b:=true;
|
||||||
|
for i:=0 to 31 do
|
||||||
|
if tsetconstnode(right).value_set^[i]<>tsetconstnode(left).value_set^[i] then
|
||||||
|
begin
|
||||||
|
b:=false;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
t:=cordconstnode.create(ord(b),booltype);
|
||||||
|
end;
|
||||||
|
lten :
|
||||||
|
begin
|
||||||
|
b := true;
|
||||||
|
For i := 0 to 31 Do
|
||||||
|
If (tsetconstnode(right).value_set^[i] And tsetconstnode(left).value_set^[i]) <>
|
||||||
|
tsetconstnode(left).value_set^[i] Then
|
||||||
|
Begin
|
||||||
|
b := false;
|
||||||
|
Break
|
||||||
|
End;
|
||||||
|
t := cordconstnode.create(ord(b),booltype);
|
||||||
|
End;
|
||||||
|
gten :
|
||||||
|
Begin
|
||||||
|
b := true;
|
||||||
|
For i := 0 to 31 Do
|
||||||
|
If (tsetconstnode(left).value_set^[i] And tsetconstnode(right).value_set^[i]) <>
|
||||||
|
tsetconstnode(right).value_set^[i] Then
|
||||||
|
Begin
|
||||||
|
b := false;
|
||||||
|
Break
|
||||||
|
End;
|
||||||
|
t := cordconstnode.create(ord(b),booltype);
|
||||||
|
End;
|
||||||
|
end;
|
||||||
|
dispose(resultset);
|
||||||
|
resulttypepass(t);
|
||||||
|
result:=t;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
{ allow operator overloading }
|
{ allow operator overloading }
|
||||||
hp:=self;
|
hp:=self;
|
||||||
if isbinaryoverloaded(hp) then
|
if isbinaryoverloaded(hp) then
|
||||||
@ -147,7 +461,62 @@ implementation
|
|||||||
inserttypeconv(left,right.resulttype);
|
inserttypeconv(left,right.resulttype);
|
||||||
ttypeconvnode(left).convtype:=tc_bool_2_int;
|
ttypeconvnode(left).convtype:=tc_bool_2_int;
|
||||||
include(left.flags,nf_explizit);
|
include(left.flags,nf_explizit);
|
||||||
end
|
end;
|
||||||
|
case nodetype of
|
||||||
|
xorn,
|
||||||
|
ltn,
|
||||||
|
lten,
|
||||||
|
gtn,
|
||||||
|
gten,
|
||||||
|
andn,
|
||||||
|
orn:
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
unequaln,
|
||||||
|
equaln:
|
||||||
|
begin
|
||||||
|
if not(cs_full_boolean_eval in aktlocalswitches) then
|
||||||
|
begin
|
||||||
|
{ Remove any compares with constants }
|
||||||
|
if (left.nodetype=ordconstn) then
|
||||||
|
begin
|
||||||
|
hp:=right;
|
||||||
|
b:=(tordconstnode(left).value<>0);
|
||||||
|
ot:=nodetype;
|
||||||
|
left.free;
|
||||||
|
left:=nil;
|
||||||
|
right:=nil;
|
||||||
|
if (not(b) and (ot=equaln)) or
|
||||||
|
(b and (ot=unequaln)) then
|
||||||
|
begin
|
||||||
|
hp:=cnotnode.create(hp);
|
||||||
|
resulttypepass(hp);
|
||||||
|
end;
|
||||||
|
result:=hp;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if (right.nodetype=ordconstn) then
|
||||||
|
begin
|
||||||
|
hp:=left;
|
||||||
|
b:=(tordconstnode(right).value<>0);
|
||||||
|
ot:=nodetype;
|
||||||
|
right.free;
|
||||||
|
right:=nil;
|
||||||
|
left:=nil;
|
||||||
|
if (not(b) and (ot=equaln)) or
|
||||||
|
(b and (ot=unequaln)) then
|
||||||
|
begin
|
||||||
|
hp:=cnotnode.create(hp);
|
||||||
|
resulttypepass(hp);
|
||||||
|
end;
|
||||||
|
result:=hp;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
CGMessage(type_e_mismatch);
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
{ Both are chars? }
|
{ Both are chars? }
|
||||||
else if is_char(rd) and is_char(ld) then
|
else if is_char(rd) and is_char(ld) then
|
||||||
@ -565,23 +934,10 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
function taddnode.pass_1 : tnode;
|
function taddnode.pass_1 : tnode;
|
||||||
|
|
||||||
var
|
var
|
||||||
t,hp : tnode;
|
hp : tnode;
|
||||||
ot,
|
|
||||||
lt,rt : tnodetype;
|
lt,rt : tnodetype;
|
||||||
rv,lv : tconstexprint;
|
|
||||||
rvd,lvd : bestreal;
|
|
||||||
rd,ld : pdef;
|
rd,ld : pdef;
|
||||||
concatstrings : boolean;
|
|
||||||
|
|
||||||
{ to evalute const sets }
|
|
||||||
resultset : pconstset;
|
|
||||||
i : longint;
|
|
||||||
b : boolean;
|
|
||||||
s1,s2 : pchar;
|
|
||||||
l1,l2 : longint;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
{ first do the two subtrees }
|
{ first do the two subtrees }
|
||||||
@ -596,284 +952,6 @@ implementation
|
|||||||
rt:=right.nodetype;
|
rt:=right.nodetype;
|
||||||
lt:=left.nodetype;
|
lt:=left.nodetype;
|
||||||
|
|
||||||
{ both are int constants }
|
|
||||||
if (((is_constintnode(left) and is_constintnode(right)) or
|
|
||||||
(is_constboolnode(left) and is_constboolnode(right) and
|
|
||||||
(nodetype in [ltn,lten,gtn,gten,equaln,unequaln,andn,xorn,orn])))) or
|
|
||||||
{ support pointer arithmetics on constants (JM) }
|
|
||||||
((lt = pointerconstn) and is_constintnode(right) and
|
|
||||||
(nodetype in [addn,subn])) or
|
|
||||||
((lt = pointerconstn) and (rt = pointerconstn) and
|
|
||||||
(nodetype in [ltn,lten,gtn,gten,equaln,unequaln,subn])) then
|
|
||||||
begin
|
|
||||||
if (lt = ordconstn) then
|
|
||||||
lv:=tordconstnode(left).value
|
|
||||||
else
|
|
||||||
lv:=tpointerconstnode(left).value;
|
|
||||||
if (rt = ordconstn) then
|
|
||||||
rv:=tordconstnode(right).value
|
|
||||||
else
|
|
||||||
rv:=tpointerconstnode(right).value;
|
|
||||||
if (lt = pointerconstn) and
|
|
||||||
(rt <> pointerconstn) then
|
|
||||||
rv := rv * ppointerdef(left.resulttype.def)^.pointertype.def^.size;
|
|
||||||
if (rt = pointerconstn) and
|
|
||||||
(lt <> pointerconstn) then
|
|
||||||
lv := lv * ppointerdef(right.resulttype.def)^.pointertype.def^.size;
|
|
||||||
case nodetype of
|
|
||||||
addn :
|
|
||||||
if (lt <> pointerconstn) then
|
|
||||||
t := cordconstnode.create(lv+rv,resulttype)
|
|
||||||
else
|
|
||||||
t := cpointerconstnode.create(lv+rv,resulttype);
|
|
||||||
subn :
|
|
||||||
if (lt <> pointerconstn) or (rt = pointerconstn) then
|
|
||||||
t := cordconstnode.create(lv-rv,resulttype)
|
|
||||||
else
|
|
||||||
t := cpointerconstnode.create(lv-rv,resulttype);
|
|
||||||
muln :
|
|
||||||
t:=cordconstnode.create(lv*rv,resulttype);
|
|
||||||
xorn :
|
|
||||||
t:=cordconstnode.create(lv xor rv,resulttype);
|
|
||||||
orn :
|
|
||||||
t:=cordconstnode.create(lv or rv,resulttype);
|
|
||||||
andn :
|
|
||||||
t:=cordconstnode.create(lv and rv,resulttype);
|
|
||||||
ltn :
|
|
||||||
t:=cordconstnode.create(ord(lv<rv),resulttype);
|
|
||||||
lten :
|
|
||||||
t:=cordconstnode.create(ord(lv<=rv),resulttype);
|
|
||||||
gtn :
|
|
||||||
t:=cordconstnode.create(ord(lv>rv),resulttype);
|
|
||||||
gten :
|
|
||||||
t:=cordconstnode.create(ord(lv>=rv),resulttype);
|
|
||||||
equaln :
|
|
||||||
t:=cordconstnode.create(ord(lv=rv),resulttype);
|
|
||||||
unequaln :
|
|
||||||
t:=cordconstnode.create(ord(lv<>rv),resulttype);
|
|
||||||
slashn :
|
|
||||||
begin
|
|
||||||
{ int/int becomes a real }
|
|
||||||
if int(rv)=0 then
|
|
||||||
begin
|
|
||||||
Message(parser_e_invalid_float_operation);
|
|
||||||
t:=crealconstnode.create(0,resulttype);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
t:=crealconstnode.create(int(lv)/int(rv),resulttype);
|
|
||||||
end;
|
|
||||||
else
|
|
||||||
CGMessage(type_e_mismatch);
|
|
||||||
end;
|
|
||||||
firstpass(t);
|
|
||||||
result:=t;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ both real constants ? }
|
|
||||||
if (lt=realconstn) and (rt=realconstn) then
|
|
||||||
begin
|
|
||||||
lvd:=trealconstnode(left).value_real;
|
|
||||||
rvd:=trealconstnode(right).value_real;
|
|
||||||
case nodetype of
|
|
||||||
addn :
|
|
||||||
t:=crealconstnode.create(lvd+rvd,pbestrealtype^);
|
|
||||||
subn :
|
|
||||||
t:=crealconstnode.create(lvd-rvd,pbestrealtype^);
|
|
||||||
muln :
|
|
||||||
t:=crealconstnode.create(lvd*rvd,pbestrealtype^);
|
|
||||||
starstarn,
|
|
||||||
caretn :
|
|
||||||
begin
|
|
||||||
if lvd<0 then
|
|
||||||
begin
|
|
||||||
Message(parser_e_invalid_float_operation);
|
|
||||||
t:=crealconstnode.create(0,pbestrealtype^);
|
|
||||||
end
|
|
||||||
else if lvd=0 then
|
|
||||||
t:=crealconstnode.create(1.0,pbestrealtype^)
|
|
||||||
else
|
|
||||||
t:=crealconstnode.create(exp(ln(lvd)*rvd),pbestrealtype^);
|
|
||||||
end;
|
|
||||||
slashn :
|
|
||||||
begin
|
|
||||||
if rvd=0 then
|
|
||||||
begin
|
|
||||||
Message(parser_e_invalid_float_operation);
|
|
||||||
t:=crealconstnode.create(0,pbestrealtype^);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
t:=crealconstnode.create(lvd/rvd,pbestrealtype^);
|
|
||||||
end;
|
|
||||||
ltn :
|
|
||||||
t:=cordconstnode.create(ord(lvd<rvd),booltype);
|
|
||||||
lten :
|
|
||||||
t:=cordconstnode.create(ord(lvd<=rvd),booltype);
|
|
||||||
gtn :
|
|
||||||
t:=cordconstnode.create(ord(lvd>rvd),booltype);
|
|
||||||
gten :
|
|
||||||
t:=cordconstnode.create(ord(lvd>=rvd),booltype);
|
|
||||||
equaln :
|
|
||||||
t:=cordconstnode.create(ord(lvd=rvd),booltype);
|
|
||||||
unequaln :
|
|
||||||
t:=cordconstnode.create(ord(lvd<>rvd),booltype);
|
|
||||||
else
|
|
||||||
CGMessage(type_e_mismatch);
|
|
||||||
end;
|
|
||||||
firstpass(t);
|
|
||||||
result:=t;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ concating strings ? }
|
|
||||||
concatstrings:=false;
|
|
||||||
s1:=nil;
|
|
||||||
s2:=nil;
|
|
||||||
if (lt=ordconstn) and (rt=ordconstn) and
|
|
||||||
is_char(ld) and is_char(rd) then
|
|
||||||
begin
|
|
||||||
s1:=strpnew(char(byte(tordconstnode(left).value)));
|
|
||||||
s2:=strpnew(char(byte(tordconstnode(right).value)));
|
|
||||||
l1:=1;
|
|
||||||
l2:=1;
|
|
||||||
concatstrings:=true;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if (lt=stringconstn) and (rt=ordconstn) and is_char(rd) then
|
|
||||||
begin
|
|
||||||
s1:=tstringconstnode(left).getpcharcopy;
|
|
||||||
l1:=tstringconstnode(left).len;
|
|
||||||
s2:=strpnew(char(byte(tordconstnode(right).value)));
|
|
||||||
l2:=1;
|
|
||||||
concatstrings:=true;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if (lt=ordconstn) and (rt=stringconstn) and is_char(ld) then
|
|
||||||
begin
|
|
||||||
s1:=strpnew(char(byte(tordconstnode(left).value)));
|
|
||||||
l1:=1;
|
|
||||||
s2:=tstringconstnode(right).getpcharcopy;
|
|
||||||
l2:=tstringconstnode(right).len;
|
|
||||||
concatstrings:=true;
|
|
||||||
end
|
|
||||||
else if (lt=stringconstn) and (rt=stringconstn) then
|
|
||||||
begin
|
|
||||||
s1:=tstringconstnode(left).getpcharcopy;
|
|
||||||
l1:=tstringconstnode(left).len;
|
|
||||||
s2:=tstringconstnode(right).getpcharcopy;
|
|
||||||
l2:=tstringconstnode(right).len;
|
|
||||||
concatstrings:=true;
|
|
||||||
end;
|
|
||||||
if concatstrings then
|
|
||||||
begin
|
|
||||||
case nodetype of
|
|
||||||
addn :
|
|
||||||
t:=cstringconstnode.createpchar(concatansistrings(s1,s2,l1,l2),l1+l2);
|
|
||||||
ltn :
|
|
||||||
t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)<0),booltype);
|
|
||||||
lten :
|
|
||||||
t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)<=0),booltype);
|
|
||||||
gtn :
|
|
||||||
t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)>0),booltype);
|
|
||||||
gten :
|
|
||||||
t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)>=0),booltype);
|
|
||||||
equaln :
|
|
||||||
t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)=0),booltype);
|
|
||||||
unequaln :
|
|
||||||
t:=cordconstnode.create(byte(compareansistrings(s1,s2,l1,l2)<>0),booltype);
|
|
||||||
end;
|
|
||||||
ansistringdispose(s1,l1);
|
|
||||||
ansistringdispose(s2,l2);
|
|
||||||
firstpass(t);
|
|
||||||
result:=t;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ set constant evaluation }
|
|
||||||
if (right.nodetype=setconstn) and
|
|
||||||
not assigned(tsetconstnode(right).left) and
|
|
||||||
(left.nodetype=setconstn) and
|
|
||||||
not assigned(tsetconstnode(left).left) then
|
|
||||||
begin
|
|
||||||
new(resultset);
|
|
||||||
case nodetype of
|
|
||||||
addn :
|
|
||||||
begin
|
|
||||||
for i:=0 to 31 do
|
|
||||||
resultset^[i]:=tsetconstnode(right).value_set^[i] or tsetconstnode(left).value_set^[i];
|
|
||||||
t:=csetconstnode.create(resultset,left.resulttype);
|
|
||||||
end;
|
|
||||||
muln :
|
|
||||||
begin
|
|
||||||
for i:=0 to 31 do
|
|
||||||
resultset^[i]:=tsetconstnode(right).value_set^[i] and tsetconstnode(left).value_set^[i];
|
|
||||||
t:=csetconstnode.create(resultset,left.resulttype);
|
|
||||||
end;
|
|
||||||
subn :
|
|
||||||
begin
|
|
||||||
for i:=0 to 31 do
|
|
||||||
resultset^[i]:=tsetconstnode(left).value_set^[i] and not(tsetconstnode(right).value_set^[i]);
|
|
||||||
t:=csetconstnode.create(resultset,left.resulttype);
|
|
||||||
end;
|
|
||||||
symdifn :
|
|
||||||
begin
|
|
||||||
for i:=0 to 31 do
|
|
||||||
resultset^[i]:=tsetconstnode(left).value_set^[i] xor tsetconstnode(right).value_set^[i];
|
|
||||||
t:=csetconstnode.create(resultset,left.resulttype);
|
|
||||||
end;
|
|
||||||
unequaln :
|
|
||||||
begin
|
|
||||||
b:=true;
|
|
||||||
for i:=0 to 31 do
|
|
||||||
if tsetconstnode(right).value_set^[i]=tsetconstnode(left).value_set^[i] then
|
|
||||||
begin
|
|
||||||
b:=false;
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
t:=cordconstnode.create(ord(b),booltype);
|
|
||||||
end;
|
|
||||||
equaln :
|
|
||||||
begin
|
|
||||||
b:=true;
|
|
||||||
for i:=0 to 31 do
|
|
||||||
if tsetconstnode(right).value_set^[i]<>tsetconstnode(left).value_set^[i] then
|
|
||||||
begin
|
|
||||||
b:=false;
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
t:=cordconstnode.create(ord(b),booltype);
|
|
||||||
end;
|
|
||||||
lten :
|
|
||||||
begin
|
|
||||||
b := true;
|
|
||||||
For i := 0 to 31 Do
|
|
||||||
If (tsetconstnode(right).value_set^[i] And tsetconstnode(left).value_set^[i]) <>
|
|
||||||
tsetconstnode(left).value_set^[i] Then
|
|
||||||
Begin
|
|
||||||
b := false;
|
|
||||||
Break
|
|
||||||
End;
|
|
||||||
t := cordconstnode.create(ord(b),booltype);
|
|
||||||
End;
|
|
||||||
gten :
|
|
||||||
Begin
|
|
||||||
b := true;
|
|
||||||
For i := 0 to 31 Do
|
|
||||||
If (tsetconstnode(left).value_set^[i] And tsetconstnode(right).value_set^[i]) <>
|
|
||||||
tsetconstnode(right).value_set^[i] Then
|
|
||||||
Begin
|
|
||||||
b := false;
|
|
||||||
Break
|
|
||||||
End;
|
|
||||||
t := cordconstnode.create(ord(b),booltype);
|
|
||||||
End;
|
|
||||||
end;
|
|
||||||
dispose(resultset);
|
|
||||||
firstpass(t);
|
|
||||||
result:=t;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ int/int gives real/real! }
|
{ int/int gives real/real! }
|
||||||
if nodetype=slashn then
|
if nodetype=slashn then
|
||||||
begin
|
begin
|
||||||
@ -894,71 +972,20 @@ implementation
|
|||||||
{ 2 booleans ? }
|
{ 2 booleans ? }
|
||||||
if is_boolean(ld) and is_boolean(rd) then
|
if is_boolean(ld) and is_boolean(rd) then
|
||||||
begin
|
begin
|
||||||
if (cs_full_boolean_eval in aktlocalswitches) or
|
if not(cs_full_boolean_eval in aktlocalswitches) and
|
||||||
(nodetype in [xorn,ltn,lten,gtn,gten]) then
|
(nodetype in [andn,orn]) then
|
||||||
begin
|
begin
|
||||||
if (left.location.loc in [LOC_JUMP,LOC_FLAGS]) and
|
calcregisters(self,0,0,0);
|
||||||
(left.location.loc in [LOC_JUMP,LOC_FLAGS]) then
|
location.loc:=LOC_JUMP;
|
||||||
calcregisters(self,2,0,0)
|
end
|
||||||
else
|
|
||||||
calcregisters(self,1,0,0);
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
case nodetype of
|
begin
|
||||||
andn,
|
if (left.location.loc in [LOC_JUMP,LOC_FLAGS]) and
|
||||||
orn:
|
(left.location.loc in [LOC_JUMP,LOC_FLAGS]) then
|
||||||
begin
|
calcregisters(self,2,0,0)
|
||||||
calcregisters(self,0,0,0);
|
else
|
||||||
location.loc:=LOC_JUMP;
|
calcregisters(self,1,0,0);
|
||||||
end;
|
end;
|
||||||
unequaln,
|
|
||||||
equaln:
|
|
||||||
begin
|
|
||||||
{ Remove any compares with constants }
|
|
||||||
if (left.nodetype=ordconstn) then
|
|
||||||
begin
|
|
||||||
hp:=right;
|
|
||||||
b:=(tordconstnode(left).value<>0);
|
|
||||||
ot:=nodetype;
|
|
||||||
left.free;
|
|
||||||
left:=nil;
|
|
||||||
right:=nil;
|
|
||||||
if (not(b) and (ot=equaln)) or
|
|
||||||
(b and (ot=unequaln)) then
|
|
||||||
begin
|
|
||||||
hp:=cnotnode.create(hp);
|
|
||||||
firstpass(hp);
|
|
||||||
end;
|
|
||||||
result:=hp;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
if (right.nodetype=ordconstn) then
|
|
||||||
begin
|
|
||||||
hp:=left;
|
|
||||||
b:=(tordconstnode(right).value<>0);
|
|
||||||
ot:=nodetype;
|
|
||||||
right.free;
|
|
||||||
right:=nil;
|
|
||||||
left:=nil;
|
|
||||||
|
|
||||||
if (not(b) and (ot=equaln)) or
|
|
||||||
(b and (ot=unequaln)) then
|
|
||||||
begin
|
|
||||||
hp:=cnotnode.create(hp);
|
|
||||||
firstpass(hp);
|
|
||||||
end;
|
|
||||||
result:=hp;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
if (left.location.loc in [LOC_JUMP,LOC_FLAGS]) and
|
|
||||||
(left.location.loc in [LOC_JUMP,LOC_FLAGS]) then
|
|
||||||
calcregisters(self,2,0,0)
|
|
||||||
else
|
|
||||||
calcregisters(self,1,0,0);
|
|
||||||
end;
|
|
||||||
else
|
|
||||||
CGMessage(type_e_mismatch);
|
|
||||||
end;
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
{ Both are chars? only convert to shortstrings for addn }
|
{ Both are chars? only convert to shortstrings for addn }
|
||||||
@ -1170,7 +1197,10 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.23 2001-04-02 21:20:30 peter
|
Revision 1.24 2001-04-04 22:42:39 peter
|
||||||
|
* move constant folding into det_resulttype
|
||||||
|
|
||||||
|
Revision 1.23 2001/04/02 21:20:30 peter
|
||||||
* resulttype rewrite
|
* resulttype rewrite
|
||||||
|
|
||||||
Revision 1.22 2001/02/04 11:12:17 jonas
|
Revision 1.22 2001/02/04 11:12:17 jonas
|
||||||
|
@ -1268,6 +1268,16 @@ implementation
|
|||||||
{ ensure that the result type is set }
|
{ ensure that the result type is set }
|
||||||
resulttype:=procdefinition^.rettype;
|
resulttype:=procdefinition^.rettype;
|
||||||
|
|
||||||
|
{ constructors return their current class type, not the type where the
|
||||||
|
constructor is declared, this can be different because of inheritance }
|
||||||
|
if (procdefinition^.proctypeoption=potype_constructor) then
|
||||||
|
begin
|
||||||
|
if assigned(methodpointer) and
|
||||||
|
assigned(methodpointer.resulttype.def) and
|
||||||
|
(methodpointer.resulttype.def^.deftype=classrefdef) then
|
||||||
|
resulttype:=pclassrefdef(methodpointer.resulttype.def)^.pointertype;
|
||||||
|
end;
|
||||||
|
|
||||||
{ insert type conversions }
|
{ insert type conversions }
|
||||||
if assigned(left) then
|
if assigned(left) then
|
||||||
tcallparanode(left).insert_typeconv(tparaitem(procdefinition^.Para.first),true);
|
tcallparanode(left).insert_typeconv(tparaitem(procdefinition^.Para.first),true);
|
||||||
@ -1388,13 +1398,12 @@ implementation
|
|||||||
begin
|
begin
|
||||||
{ extra handling of classes }
|
{ extra handling of classes }
|
||||||
{ methodpointer should be assigned! }
|
{ methodpointer should be assigned! }
|
||||||
if assigned(methodpointer) and assigned(methodpointer.resulttype.def) and
|
if assigned(methodpointer) and
|
||||||
(methodpointer.resulttype.def^.deftype=classrefdef) then
|
assigned(methodpointer.resulttype.def) and
|
||||||
|
(methodpointer.resulttype.def^.deftype=classrefdef) then
|
||||||
begin
|
begin
|
||||||
location.loc:=LOC_REGISTER;
|
location.loc:=LOC_REGISTER;
|
||||||
registers32:=1;
|
registers32:=1;
|
||||||
{ the result type depends on the classref }
|
|
||||||
resulttype:=pclassrefdef(methodpointer.resulttype.def)^.pointertype;
|
|
||||||
end
|
end
|
||||||
{ a object constructor returns the result with the flags }
|
{ a object constructor returns the result with the flags }
|
||||||
else
|
else
|
||||||
@ -1604,7 +1613,10 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.25 2001-04-02 21:20:30 peter
|
Revision 1.26 2001-04-04 22:42:39 peter
|
||||||
|
* move constant folding into det_resulttype
|
||||||
|
|
||||||
|
Revision 1.25 2001/04/02 21:20:30 peter
|
||||||
* resulttype rewrite
|
* resulttype rewrite
|
||||||
|
|
||||||
Revision 1.24 2001/03/12 12:47:46 michael
|
Revision 1.24 2001/03/12 12:47:46 michael
|
||||||
|
@ -40,6 +40,15 @@ interface
|
|||||||
function pass_1 : tnode;override;
|
function pass_1 : tnode;override;
|
||||||
function det_resulttype:tnode;override;
|
function det_resulttype:tnode;override;
|
||||||
function docompare(p: tnode) : boolean; override;
|
function docompare(p: tnode) : boolean; override;
|
||||||
|
private
|
||||||
|
function resulttype_cord_to_pointer : tnode;
|
||||||
|
function resulttype_string_to_string : tnode;
|
||||||
|
function resulttype_char_to_string : tnode;
|
||||||
|
function resulttype_int_to_real : tnode;
|
||||||
|
function resulttype_real_to_real : tnode;
|
||||||
|
function resulttype_cchar_to_pchar : tnode;
|
||||||
|
function resulttype_arrayconstructor_to_set : tnode;
|
||||||
|
function resulttype_call_helper(c : tconverttype) : tnode;
|
||||||
protected
|
protected
|
||||||
function first_int_to_int : tnode;virtual;
|
function first_int_to_int : tnode;virtual;
|
||||||
function first_cstring_to_pchar : tnode;virtual;
|
function first_cstring_to_pchar : tnode;virtual;
|
||||||
@ -218,10 +227,9 @@ implementation
|
|||||||
p.left:=nil;
|
p.left:=nil;
|
||||||
p3:=nil;
|
p3:=nil;
|
||||||
end;
|
end;
|
||||||
{$warning todo: firstpass}
|
resulttypepass(p2);
|
||||||
firstpass(p2);
|
|
||||||
if assigned(p3) then
|
if assigned(p3) then
|
||||||
firstpass(p3);
|
resulttypepass(p3);
|
||||||
if codegenerror then
|
if codegenerror then
|
||||||
break;
|
break;
|
||||||
case p2.resulttype.def^.deftype of
|
case p2.resulttype.def^.deftype of
|
||||||
@ -382,11 +390,11 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_cord_to_pointer : tnode;
|
function ttypeconvnode.resulttype_cord_to_pointer : tnode;
|
||||||
var
|
var
|
||||||
t : tnode;
|
t : tnode;
|
||||||
begin
|
begin
|
||||||
first_cord_to_pointer:=nil;
|
result:=nil;
|
||||||
if left.nodetype=ordconstn then
|
if left.nodetype=ordconstn then
|
||||||
begin
|
begin
|
||||||
{ check if we have a valid pointer constant (JM) }
|
{ check if we have a valid pointer constant (JM) }
|
||||||
@ -406,260 +414,86 @@ implementation
|
|||||||
else
|
else
|
||||||
internalerror(2001020801);
|
internalerror(2001020801);
|
||||||
t:=cpointerconstnode.create(tpointerord(tordconstnode(left).value),resulttype);
|
t:=cpointerconstnode.create(tpointerord(tordconstnode(left).value),resulttype);
|
||||||
firstpass(t);
|
resulttypepass(t);
|
||||||
first_cord_to_pointer:=t;
|
result:=t;
|
||||||
exit;
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
internalerror(432472389);
|
internalerror(200104023);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_int_to_int : tnode;
|
function ttypeconvnode.resulttype_string_to_string : tnode;
|
||||||
begin
|
begin
|
||||||
first_int_to_int:=nil;
|
result:=nil;
|
||||||
if (left.location.loc<>LOC_REGISTER) and
|
if left.nodetype=stringconstn then
|
||||||
(resulttype.def^.size>left.resulttype.def^.size) then
|
begin
|
||||||
location.loc:=LOC_REGISTER;
|
tstringconstnode(left).st_type:=pstringdef(resulttype.def)^.string_typ;
|
||||||
if is_64bitint(resulttype.def) then
|
tstringconstnode(left).resulttype:=resulttype;
|
||||||
registers32:=max(registers32,2)
|
result:=left;
|
||||||
else
|
left:=nil;
|
||||||
registers32:=max(registers32,1);
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_cstring_to_pchar : tnode;
|
function ttypeconvnode.resulttype_char_to_string : tnode;
|
||||||
begin
|
|
||||||
first_cstring_to_pchar:=nil;
|
|
||||||
registers32:=1;
|
|
||||||
location.loc:=LOC_REGISTER;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_string_to_chararray : tnode;
|
|
||||||
begin
|
|
||||||
first_string_to_chararray:=nil;
|
|
||||||
registers32:=1;
|
|
||||||
location.loc:=LOC_REGISTER;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_string_to_string : tnode;
|
|
||||||
begin
|
|
||||||
first_string_to_string:=nil;
|
|
||||||
if pstringdef(resulttype.def)^.string_typ<>
|
|
||||||
pstringdef(left.resulttype.def)^.string_typ then
|
|
||||||
begin
|
|
||||||
if left.nodetype=stringconstn then
|
|
||||||
begin
|
|
||||||
tstringconstnode(left).st_type:=pstringdef(resulttype.def)^.string_typ;
|
|
||||||
tstringconstnode(left).resulttype:=resulttype;
|
|
||||||
{ remove typeconv node }
|
|
||||||
first_string_to_string:=left;
|
|
||||||
left:=nil;
|
|
||||||
exit;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
procinfo^.flags:=procinfo^.flags or pi_do_call;
|
|
||||||
end;
|
|
||||||
{ for simplicity lets first keep all ansistrings
|
|
||||||
as LOC_MEM, could also become LOC_REGISTER }
|
|
||||||
if pstringdef(resulttype.def)^.string_typ in [st_ansistring,st_widestring] then
|
|
||||||
{ we may use ansistrings so no fast exit here }
|
|
||||||
procinfo^.no_fast_exit:=true;
|
|
||||||
location.loc:=LOC_MEM;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_char_to_string : tnode;
|
|
||||||
var
|
var
|
||||||
hp : tstringconstnode;
|
hp : tstringconstnode;
|
||||||
begin
|
begin
|
||||||
first_char_to_string:=nil;
|
result:=nil;
|
||||||
if left.nodetype=ordconstn then
|
if left.nodetype=ordconstn then
|
||||||
begin
|
begin
|
||||||
hp:=cstringconstnode.createstr(chr(tordconstnode(left).value),st_default);
|
hp:=cstringconstnode.createstr(chr(tordconstnode(left).value),st_default);
|
||||||
hp.st_type:=pstringdef(resulttype.def)^.string_typ;
|
hp.st_type:=pstringdef(resulttype.def)^.string_typ;
|
||||||
firstpass(hp);
|
resulttypepass(hp);
|
||||||
first_char_to_string:=hp;
|
result:=hp;
|
||||||
end
|
end;
|
||||||
else
|
|
||||||
location.loc:=LOC_MEM;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_nothing : tnode;
|
function ttypeconvnode.resulttype_int_to_real : tnode;
|
||||||
begin
|
|
||||||
first_nothing:=nil;
|
|
||||||
location.loc:=LOC_MEM;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_array_to_pointer : tnode;
|
|
||||||
begin
|
|
||||||
first_array_to_pointer:=nil;
|
|
||||||
if registers32<1 then
|
|
||||||
registers32:=1;
|
|
||||||
location.loc:=LOC_REGISTER;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_int_to_real : tnode;
|
|
||||||
var
|
var
|
||||||
t : trealconstnode;
|
t : trealconstnode;
|
||||||
begin
|
begin
|
||||||
first_int_to_real:=nil;
|
result:=nil;
|
||||||
if left.nodetype=ordconstn then
|
if left.nodetype=ordconstn then
|
||||||
begin
|
begin
|
||||||
t:=crealconstnode.create(tordconstnode(left).value,resulttype);
|
t:=crealconstnode.create(tordconstnode(left).value,resulttype);
|
||||||
firstpass(t);
|
resulttypepass(t);
|
||||||
first_int_to_real:=t;
|
result:=t;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
if registersfpu<1 then
|
|
||||||
registersfpu:=1;
|
|
||||||
location.loc:=LOC_FPU;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_real_to_real : tnode;
|
function ttypeconvnode.resulttype_real_to_real : tnode;
|
||||||
var
|
var
|
||||||
t : tnode;
|
t : tnode;
|
||||||
begin
|
begin
|
||||||
first_real_to_real:=nil;
|
result:=nil;
|
||||||
if left.nodetype=realconstn then
|
if left.nodetype=realconstn then
|
||||||
begin
|
begin
|
||||||
t:=crealconstnode.create(trealconstnode(left).value_real,resulttype);
|
t:=crealconstnode.create(trealconstnode(left).value_real,resulttype);
|
||||||
firstpass(t);
|
resulttypepass(t);
|
||||||
first_real_to_real:=t;
|
result:=t;
|
||||||
exit;
|
|
||||||
end;
|
end;
|
||||||
{ comp isn't a floating type }
|
|
||||||
{$ifdef i386}
|
|
||||||
if (pfloatdef(resulttype.def)^.typ=s64comp) and
|
|
||||||
(pfloatdef(left.resulttype.def)^.typ<>s64comp) and
|
|
||||||
not (nf_explizit in flags) then
|
|
||||||
CGMessage(type_w_convert_real_2_comp);
|
|
||||||
{$endif}
|
|
||||||
if registersfpu<1 then
|
|
||||||
registersfpu:=1;
|
|
||||||
location.loc:=LOC_FPU;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_pointer_to_array : tnode;
|
function ttypeconvnode.resulttype_cchar_to_pchar : tnode;
|
||||||
begin
|
begin
|
||||||
first_pointer_to_array:=nil;
|
result:=nil;
|
||||||
if registers32<1 then
|
|
||||||
registers32:=1;
|
|
||||||
location.loc:=LOC_REFERENCE;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_chararray_to_string : tnode;
|
|
||||||
begin
|
|
||||||
first_chararray_to_string:=nil;
|
|
||||||
{ the only important information is the location of the }
|
|
||||||
{ result }
|
|
||||||
{ other stuff is done by firsttypeconv }
|
|
||||||
location.loc:=LOC_MEM;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_cchar_to_pchar : tnode;
|
|
||||||
begin
|
|
||||||
first_cchar_to_pchar:=nil;
|
|
||||||
inserttypeconv(left,cshortstringtype);
|
inserttypeconv(left,cshortstringtype);
|
||||||
{ evaluate again, reset resulttype so the convert_typ
|
{ evaluate again, reset resulttype so the convert_typ
|
||||||
will be calculated again }
|
will be calculated again }
|
||||||
det_resulttype;
|
result:=det_resulttype;
|
||||||
first_cchar_to_pchar:=pass_1;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_bool_to_int : tnode;
|
function ttypeconvnode.resulttype_arrayconstructor_to_set : tnode;
|
||||||
begin
|
|
||||||
first_bool_to_int:=nil;
|
|
||||||
{ byte(boolean) or word(wordbool) or longint(longbool) must
|
|
||||||
be accepted for var parameters }
|
|
||||||
if (nf_explizit in flags) and
|
|
||||||
(left.resulttype.def^.size=resulttype.def^.size) and
|
|
||||||
(left.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
|
|
||||||
exit;
|
|
||||||
location.loc:=LOC_REGISTER;
|
|
||||||
if registers32<1 then
|
|
||||||
registers32:=1;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_int_to_bool : tnode;
|
|
||||||
begin
|
|
||||||
first_int_to_bool:=nil;
|
|
||||||
{ byte(boolean) or word(wordbool) or longint(longbool) must
|
|
||||||
be accepted for var parameters }
|
|
||||||
if (nf_explizit in flags) and
|
|
||||||
(left.resulttype.def^.size=resulttype.def^.size) and
|
|
||||||
(left.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
|
|
||||||
exit;
|
|
||||||
location.loc:=LOC_REGISTER;
|
|
||||||
{ need if bool to bool !!
|
|
||||||
not very nice !!
|
|
||||||
insertypeconv(left,s32bittype);
|
|
||||||
left.explizit:=true;
|
|
||||||
firstpass(left); }
|
|
||||||
if registers32<1 then
|
|
||||||
registers32:=1;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_bool_to_bool : tnode;
|
|
||||||
begin
|
|
||||||
first_bool_to_bool:=nil;
|
|
||||||
location.loc:=LOC_REGISTER;
|
|
||||||
if registers32<1 then
|
|
||||||
registers32:=1;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_proc_to_procvar : tnode;
|
|
||||||
begin
|
|
||||||
first_proc_to_procvar:=nil;
|
|
||||||
if (left.location.loc<>LOC_REFERENCE) then
|
|
||||||
CGMessage(cg_e_illegal_expression);
|
|
||||||
registers32:=left.registers32;
|
|
||||||
if registers32<1 then
|
|
||||||
registers32:=1;
|
|
||||||
location.loc:=LOC_REGISTER;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_load_smallset : tnode;
|
|
||||||
begin
|
|
||||||
first_load_smallset:=nil;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_pchar_to_string : tnode;
|
|
||||||
begin
|
|
||||||
first_pchar_to_string:=nil;
|
|
||||||
location.loc:=LOC_REFERENCE;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_ansistring_to_pchar : tnode;
|
|
||||||
begin
|
|
||||||
first_ansistring_to_pchar:=nil;
|
|
||||||
location.loc:=LOC_REGISTER;
|
|
||||||
if registers32<1 then
|
|
||||||
registers32:=1;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function ttypeconvnode.first_arrayconstructor_to_set : tnode;
|
|
||||||
var
|
var
|
||||||
hp : tnode;
|
hp : tnode;
|
||||||
begin
|
begin
|
||||||
first_arrayconstructor_to_set:=nil;
|
result:=nil;
|
||||||
if left.nodetype<>arrayconstructorn then
|
if left.nodetype<>arrayconstructorn then
|
||||||
internalerror(5546);
|
internalerror(5546);
|
||||||
{ remove typeconv node }
|
{ remove typeconv node }
|
||||||
@ -668,64 +502,56 @@ implementation
|
|||||||
{ create a set constructor tree }
|
{ create a set constructor tree }
|
||||||
arrayconstructor_to_set(tarrayconstructornode(hp));
|
arrayconstructor_to_set(tarrayconstructornode(hp));
|
||||||
{ now resulttypepass the set }
|
{ now resulttypepass the set }
|
||||||
firstpass(hp);
|
resulttypepass(hp);
|
||||||
first_arrayconstructor_to_set:=hp;
|
result:=hp;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ttypeconvnode.first_class_to_intf : tnode;
|
|
||||||
|
|
||||||
begin
|
function ttypeconvnode.resulttype_call_helper(c : tconverttype) : tnode;
|
||||||
first_class_to_intf:=nil;
|
|
||||||
location.loc:=LOC_REFERENCE;
|
|
||||||
if registers32<1 then
|
|
||||||
registers32:=1;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function ttypeconvnode.first_call_helper(c : tconverttype) : tnode;
|
|
||||||
|
|
||||||
const
|
const
|
||||||
firstconvert : array[tconverttype] of pointer = (
|
resulttypeconvert : array[tconverttype] of pointer = (
|
||||||
@ttypeconvnode.first_nothing, {equal}
|
{equal} nil,
|
||||||
@ttypeconvnode.first_nothing, {not_possible}
|
{not_possible} nil,
|
||||||
@ttypeconvnode.first_string_to_string,
|
{ string_2_string } @ttypeconvnode.resulttype_string_to_string,
|
||||||
@ttypeconvnode.first_char_to_string,
|
{ char_2_string } @ttypeconvnode.resulttype_char_to_string,
|
||||||
@ttypeconvnode.first_pchar_to_string,
|
{ pchar_2_string } nil,
|
||||||
@ttypeconvnode.first_cchar_to_pchar,
|
{ cchar_2_pchar } @ttypeconvnode.resulttype_cchar_to_pchar,
|
||||||
@ttypeconvnode.first_cstring_to_pchar,
|
{ cstring_2_pchar } nil,
|
||||||
@ttypeconvnode.first_ansistring_to_pchar,
|
{ ansistring_2_pchar } nil,
|
||||||
@ttypeconvnode.first_string_to_chararray,
|
{ string_2_chararray } nil,
|
||||||
@ttypeconvnode.first_chararray_to_string,
|
{ chararray_2_string } nil,
|
||||||
@ttypeconvnode.first_array_to_pointer,
|
{ array_2_pointer } nil,
|
||||||
@ttypeconvnode.first_pointer_to_array,
|
{ pointer_2_array } nil,
|
||||||
@ttypeconvnode.first_int_to_int,
|
{ int_2_int } nil,
|
||||||
@ttypeconvnode.first_int_to_bool,
|
{ int_2_bool } nil,
|
||||||
@ttypeconvnode.first_bool_to_bool,
|
{ bool_2_bool } nil,
|
||||||
@ttypeconvnode.first_bool_to_int,
|
{ bool_2_int } nil,
|
||||||
@ttypeconvnode.first_real_to_real,
|
{ real_2_real } @ttypeconvnode.resulttype_real_to_real,
|
||||||
@ttypeconvnode.first_int_to_real,
|
{ int_2_real } @ttypeconvnode.resulttype_int_to_real,
|
||||||
@ttypeconvnode.first_proc_to_procvar,
|
{ proc_2_procvar } nil,
|
||||||
@ttypeconvnode.first_arrayconstructor_to_set,
|
{ arrayconstructor_2_set } @ttypeconvnode.resulttype_arrayconstructor_to_set,
|
||||||
@ttypeconvnode.first_load_smallset,
|
{ load_smallset } nil,
|
||||||
@ttypeconvnode.first_cord_to_pointer,
|
{ cord_2_pointer } @ttypeconvnode.resulttype_cord_to_pointer,
|
||||||
@ttypeconvnode.first_nothing,
|
{ intf_2_string } nil,
|
||||||
@ttypeconvnode.first_nothing,
|
{ intf_2_guid } nil,
|
||||||
@ttypeconvnode.first_class_to_intf
|
{ class_2_intf } nil
|
||||||
);
|
);
|
||||||
type
|
type
|
||||||
tprocedureofobject = function : tnode of object;
|
tprocedureofobject = function : tnode of object;
|
||||||
|
|
||||||
var
|
var
|
||||||
r : packed record
|
r : packed record
|
||||||
proc : pointer;
|
proc : pointer;
|
||||||
obj : pointer;
|
obj : pointer;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
result:=nil;
|
||||||
{ this is a little bit dirty but it works }
|
{ this is a little bit dirty but it works }
|
||||||
{ and should be quite portable too }
|
{ and should be quite portable too }
|
||||||
r.proc:=firstconvert[c];
|
r.proc:=resulttypeconvert[c];
|
||||||
r.obj:=self;
|
r.obj:=self;
|
||||||
first_call_helper:=tprocedureofobject(r){$ifdef FPC}();{$endif FPC}
|
if assigned(r.proc) then
|
||||||
|
result:=tprocedureofobject(r){$ifdef FPC}();{$endif FPC}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -784,8 +610,6 @@ implementation
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$WARNING Todo: remove firstpass}
|
|
||||||
firstpass(left);
|
|
||||||
if isconvertable(left.resulttype.def,resulttype.def,convtype,left.nodetype,nf_explizit in flags)=0 then
|
if isconvertable(left.resulttype.def,resulttype.def,convtype,left.nodetype,nf_explizit in flags)=0 then
|
||||||
begin
|
begin
|
||||||
{Procedures have a resulttype.def of voiddef and functions of their
|
{Procedures have a resulttype.def of voiddef and functions of their
|
||||||
@ -1025,6 +849,277 @@ implementation
|
|||||||
result:=hp;
|
result:=hp;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ now call the resulttype helper to do constant folding }
|
||||||
|
result:=resulttype_call_helper(convtype);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_cord_to_pointer : tnode;
|
||||||
|
begin
|
||||||
|
result:=nil;
|
||||||
|
internalerror(200104043);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_int_to_int : tnode;
|
||||||
|
begin
|
||||||
|
first_int_to_int:=nil;
|
||||||
|
if (left.location.loc<>LOC_REGISTER) and
|
||||||
|
(resulttype.def^.size>left.resulttype.def^.size) then
|
||||||
|
location.loc:=LOC_REGISTER;
|
||||||
|
if is_64bitint(resulttype.def) then
|
||||||
|
registers32:=max(registers32,2)
|
||||||
|
else
|
||||||
|
registers32:=max(registers32,1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_cstring_to_pchar : tnode;
|
||||||
|
begin
|
||||||
|
first_cstring_to_pchar:=nil;
|
||||||
|
registers32:=1;
|
||||||
|
location.loc:=LOC_REGISTER;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_string_to_chararray : tnode;
|
||||||
|
begin
|
||||||
|
first_string_to_chararray:=nil;
|
||||||
|
registers32:=1;
|
||||||
|
location.loc:=LOC_REGISTER;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_string_to_string : tnode;
|
||||||
|
begin
|
||||||
|
first_string_to_string:=nil;
|
||||||
|
if pstringdef(resulttype.def)^.string_typ<>
|
||||||
|
pstringdef(left.resulttype.def)^.string_typ then
|
||||||
|
begin
|
||||||
|
procinfo^.flags:=procinfo^.flags or pi_do_call;
|
||||||
|
end;
|
||||||
|
{ for simplicity lets first keep all ansistrings
|
||||||
|
as LOC_MEM, could also become LOC_REGISTER }
|
||||||
|
if pstringdef(resulttype.def)^.string_typ in [st_ansistring,st_widestring] then
|
||||||
|
{ we may use ansistrings so no fast exit here }
|
||||||
|
procinfo^.no_fast_exit:=true;
|
||||||
|
location.loc:=LOC_MEM;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_char_to_string : tnode;
|
||||||
|
begin
|
||||||
|
first_char_to_string:=nil;
|
||||||
|
location.loc:=LOC_MEM;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_nothing : tnode;
|
||||||
|
begin
|
||||||
|
first_nothing:=nil;
|
||||||
|
location.loc:=LOC_MEM;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_array_to_pointer : tnode;
|
||||||
|
begin
|
||||||
|
first_array_to_pointer:=nil;
|
||||||
|
if registers32<1 then
|
||||||
|
registers32:=1;
|
||||||
|
location.loc:=LOC_REGISTER;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_int_to_real : tnode;
|
||||||
|
begin
|
||||||
|
first_int_to_real:=nil;
|
||||||
|
if registersfpu<1 then
|
||||||
|
registersfpu:=1;
|
||||||
|
location.loc:=LOC_FPU;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_real_to_real : tnode;
|
||||||
|
begin
|
||||||
|
first_real_to_real:=nil;
|
||||||
|
{ comp isn't a floating type }
|
||||||
|
{$ifdef i386}
|
||||||
|
if (pfloatdef(resulttype.def)^.typ=s64comp) and
|
||||||
|
(pfloatdef(left.resulttype.def)^.typ<>s64comp) and
|
||||||
|
not (nf_explizit in flags) then
|
||||||
|
CGMessage(type_w_convert_real_2_comp);
|
||||||
|
{$endif}
|
||||||
|
if registersfpu<1 then
|
||||||
|
registersfpu:=1;
|
||||||
|
location.loc:=LOC_FPU;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_pointer_to_array : tnode;
|
||||||
|
begin
|
||||||
|
first_pointer_to_array:=nil;
|
||||||
|
if registers32<1 then
|
||||||
|
registers32:=1;
|
||||||
|
location.loc:=LOC_REFERENCE;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_chararray_to_string : tnode;
|
||||||
|
begin
|
||||||
|
first_chararray_to_string:=nil;
|
||||||
|
{ the only important information is the location of the }
|
||||||
|
{ result }
|
||||||
|
{ other stuff is done by firsttypeconv }
|
||||||
|
location.loc:=LOC_MEM;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_cchar_to_pchar : tnode;
|
||||||
|
begin
|
||||||
|
first_cchar_to_pchar:=nil;
|
||||||
|
internalerror(200104021);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_bool_to_int : tnode;
|
||||||
|
begin
|
||||||
|
first_bool_to_int:=nil;
|
||||||
|
{ byte(boolean) or word(wordbool) or longint(longbool) must
|
||||||
|
be accepted for var parameters }
|
||||||
|
if (nf_explizit in flags) and
|
||||||
|
(left.resulttype.def^.size=resulttype.def^.size) and
|
||||||
|
(left.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
|
||||||
|
exit;
|
||||||
|
location.loc:=LOC_REGISTER;
|
||||||
|
if registers32<1 then
|
||||||
|
registers32:=1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_int_to_bool : tnode;
|
||||||
|
begin
|
||||||
|
first_int_to_bool:=nil;
|
||||||
|
{ byte(boolean) or word(wordbool) or longint(longbool) must
|
||||||
|
be accepted for var parameters }
|
||||||
|
if (nf_explizit in flags) and
|
||||||
|
(left.resulttype.def^.size=resulttype.def^.size) and
|
||||||
|
(left.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
|
||||||
|
exit;
|
||||||
|
location.loc:=LOC_REGISTER;
|
||||||
|
{ need if bool to bool !!
|
||||||
|
not very nice !!
|
||||||
|
insertypeconv(left,s32bittype);
|
||||||
|
left.explizit:=true;
|
||||||
|
firstpass(left); }
|
||||||
|
if registers32<1 then
|
||||||
|
registers32:=1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_bool_to_bool : tnode;
|
||||||
|
begin
|
||||||
|
first_bool_to_bool:=nil;
|
||||||
|
location.loc:=LOC_REGISTER;
|
||||||
|
if registers32<1 then
|
||||||
|
registers32:=1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_proc_to_procvar : tnode;
|
||||||
|
begin
|
||||||
|
first_proc_to_procvar:=nil;
|
||||||
|
if (left.location.loc<>LOC_REFERENCE) then
|
||||||
|
CGMessage(cg_e_illegal_expression);
|
||||||
|
registers32:=left.registers32;
|
||||||
|
if registers32<1 then
|
||||||
|
registers32:=1;
|
||||||
|
location.loc:=LOC_REGISTER;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_load_smallset : tnode;
|
||||||
|
begin
|
||||||
|
first_load_smallset:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_pchar_to_string : tnode;
|
||||||
|
begin
|
||||||
|
first_pchar_to_string:=nil;
|
||||||
|
location.loc:=LOC_REFERENCE;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_ansistring_to_pchar : tnode;
|
||||||
|
begin
|
||||||
|
first_ansistring_to_pchar:=nil;
|
||||||
|
location.loc:=LOC_REGISTER;
|
||||||
|
if registers32<1 then
|
||||||
|
registers32:=1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttypeconvnode.first_arrayconstructor_to_set : tnode;
|
||||||
|
begin
|
||||||
|
first_arrayconstructor_to_set:=nil;
|
||||||
|
internalerror(200104022);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ttypeconvnode.first_class_to_intf : tnode;
|
||||||
|
|
||||||
|
begin
|
||||||
|
first_class_to_intf:=nil;
|
||||||
|
location.loc:=LOC_REFERENCE;
|
||||||
|
if registers32<1 then
|
||||||
|
registers32:=1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ttypeconvnode.first_call_helper(c : tconverttype) : tnode;
|
||||||
|
|
||||||
|
const
|
||||||
|
firstconvert : array[tconverttype] of pointer = (
|
||||||
|
@ttypeconvnode.first_nothing, {equal}
|
||||||
|
@ttypeconvnode.first_nothing, {not_possible}
|
||||||
|
@ttypeconvnode.first_string_to_string,
|
||||||
|
@ttypeconvnode.first_char_to_string,
|
||||||
|
@ttypeconvnode.first_pchar_to_string,
|
||||||
|
@ttypeconvnode.first_cchar_to_pchar,
|
||||||
|
@ttypeconvnode.first_cstring_to_pchar,
|
||||||
|
@ttypeconvnode.first_ansistring_to_pchar,
|
||||||
|
@ttypeconvnode.first_string_to_chararray,
|
||||||
|
@ttypeconvnode.first_chararray_to_string,
|
||||||
|
@ttypeconvnode.first_array_to_pointer,
|
||||||
|
@ttypeconvnode.first_pointer_to_array,
|
||||||
|
@ttypeconvnode.first_int_to_int,
|
||||||
|
@ttypeconvnode.first_int_to_bool,
|
||||||
|
@ttypeconvnode.first_bool_to_bool,
|
||||||
|
@ttypeconvnode.first_bool_to_int,
|
||||||
|
@ttypeconvnode.first_real_to_real,
|
||||||
|
@ttypeconvnode.first_int_to_real,
|
||||||
|
@ttypeconvnode.first_proc_to_procvar,
|
||||||
|
@ttypeconvnode.first_arrayconstructor_to_set,
|
||||||
|
@ttypeconvnode.first_load_smallset,
|
||||||
|
@ttypeconvnode.first_cord_to_pointer,
|
||||||
|
@ttypeconvnode.first_nothing,
|
||||||
|
@ttypeconvnode.first_nothing,
|
||||||
|
@ttypeconvnode.first_class_to_intf
|
||||||
|
);
|
||||||
|
type
|
||||||
|
tprocedureofobject = function : tnode of object;
|
||||||
|
|
||||||
|
var
|
||||||
|
r : packed record
|
||||||
|
proc : pointer;
|
||||||
|
obj : pointer;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
{ this is a little bit dirty but it works }
|
||||||
|
{ and should be quite portable too }
|
||||||
|
r.proc:=firstconvert[c];
|
||||||
|
r.obj:=self;
|
||||||
|
first_call_helper:=tprocedureofobject(r){$ifdef FPC}();{$endif FPC}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1200,7 +1295,10 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.22 2001-04-02 21:20:30 peter
|
Revision 1.23 2001-04-04 22:42:39 peter
|
||||||
|
* move constant folding into det_resulttype
|
||||||
|
|
||||||
|
Revision 1.22 2001/04/02 21:20:30 peter
|
||||||
* resulttype rewrite
|
* resulttype rewrite
|
||||||
|
|
||||||
Revision 1.21 2001/03/08 17:44:47 jonas
|
Revision 1.21 2001/03/08 17:44:47 jonas
|
||||||
|
2538
compiler/ninl.pas
2538
compiler/ninl.pas
File diff suppressed because it is too large
Load Diff
@ -164,6 +164,8 @@ implementation
|
|||||||
p1 : tnode;
|
p1 : tnode;
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
|
|
||||||
|
{ optimize simple with loadings }
|
||||||
if (symtable^.symtabletype=withsymtable) and
|
if (symtable^.symtabletype=withsymtable) and
|
||||||
(pwithsymtable(symtable)^.direct_with) and
|
(pwithsymtable(symtable)^.direct_with) and
|
||||||
(symtableentry^.typ=varsym) then
|
(symtableentry^.typ=varsym) then
|
||||||
@ -312,6 +314,7 @@ implementation
|
|||||||
(symtable = tloadnode(p).symtable);
|
(symtable = tloadnode(p).symtable);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
TASSIGNMENTNODE
|
TASSIGNMENTNODE
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
@ -440,6 +443,7 @@ implementation
|
|||||||
(assigntype = tassignmentnode(p).assigntype);
|
(assigntype = tassignmentnode(p).assigntype);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
TFUNCRETNODE
|
TFUNCRETNODE
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
@ -451,6 +455,7 @@ implementation
|
|||||||
funcretprocinfo:=p;
|
funcretprocinfo:=p;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function tfuncretnode.getcopy : tnode;
|
function tfuncretnode.getcopy : tnode;
|
||||||
var
|
var
|
||||||
n : tfuncretnode;
|
n : tfuncretnode;
|
||||||
@ -460,12 +465,14 @@ implementation
|
|||||||
getcopy:=n;
|
getcopy:=n;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function tfuncretnode.det_resulttype:tnode;
|
function tfuncretnode.det_resulttype:tnode;
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
resulttype:=pprocinfo(funcretprocinfo)^.returntype;
|
resulttype:=pprocinfo(funcretprocinfo)^.returntype;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function tfuncretnode.pass_1 : tnode;
|
function tfuncretnode.pass_1 : tnode;
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
@ -475,6 +482,7 @@ implementation
|
|||||||
registers32:=1;
|
registers32:=1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function tfuncretnode.docompare(p: tnode): boolean;
|
function tfuncretnode.docompare(p: tnode): boolean;
|
||||||
begin
|
begin
|
||||||
docompare :=
|
docompare :=
|
||||||
@ -482,6 +490,7 @@ implementation
|
|||||||
(funcretprocinfo = tfuncretnode(p).funcretprocinfo);
|
(funcretprocinfo = tfuncretnode(p).funcretprocinfo);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
TARRAYCONSTRUCTORRANGENODE
|
TARRAYCONSTRUCTORRANGENODE
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
@ -519,23 +528,22 @@ implementation
|
|||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
constructor tarrayconstructornode.create(l,r : tnode);
|
constructor tarrayconstructornode.create(l,r : tnode);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
inherited create(arrayconstructorn,l,r);
|
inherited create(arrayconstructorn,l,r);
|
||||||
constructortype.reset;
|
constructortype.reset;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function tarrayconstructornode.getcopy : tnode;
|
|
||||||
|
|
||||||
|
function tarrayconstructornode.getcopy : tnode;
|
||||||
var
|
var
|
||||||
n : tarrayconstructornode;
|
n : tarrayconstructornode;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
n:=tarrayconstructornode(inherited getcopy);
|
n:=tarrayconstructornode(inherited getcopy);
|
||||||
n.constructortype:=constructortype;
|
n.constructortype:=constructortype;
|
||||||
result:=n;
|
result:=n;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function tarrayconstructornode.det_resulttype:tnode;
|
function tarrayconstructornode.det_resulttype:tnode;
|
||||||
var
|
var
|
||||||
htype : ttype;
|
htype : ttype;
|
||||||
@ -544,6 +552,7 @@ implementation
|
|||||||
varia : boolean;
|
varia : boolean;
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
|
|
||||||
{ are we allowing array constructor? Then convert it to a set }
|
{ are we allowing array constructor? Then convert it to a set }
|
||||||
if not allow_array_constructor then
|
if not allow_array_constructor then
|
||||||
begin
|
begin
|
||||||
@ -553,6 +562,7 @@ implementation
|
|||||||
result:=hp;
|
result:=hp;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ only pass left tree, right tree contains next construct if any }
|
{ only pass left tree, right tree contains next construct if any }
|
||||||
htype:=constructortype;
|
htype:=constructortype;
|
||||||
len:=0;
|
len:=0;
|
||||||
@ -589,43 +599,12 @@ implementation
|
|||||||
|
|
||||||
function tarrayconstructornode.pass_1 : tnode;
|
function tarrayconstructornode.pass_1 : tnode;
|
||||||
var
|
var
|
||||||
htype : ttype;
|
|
||||||
thp,
|
thp,
|
||||||
chp,
|
chp,
|
||||||
hp : tarrayconstructornode;
|
hp : tarrayconstructornode;
|
||||||
len : longint;
|
|
||||||
varia : boolean;
|
|
||||||
|
|
||||||
procedure postprocess(t : tnode);
|
|
||||||
|
|
||||||
begin
|
|
||||||
calcregisters(tbinarynode(t),0,0,0);
|
|
||||||
{ looks a little bit dangerous to me }
|
|
||||||
{ len-1 gives problems with is_open_array if len=0, }
|
|
||||||
{ is_open_array checks now for isconstructor (FK) }
|
|
||||||
{ if no type is set then we set the type to voiddef to overcome a
|
|
||||||
0 addressing }
|
|
||||||
if not assigned(htype.def) then
|
|
||||||
htype:=voidtype;
|
|
||||||
{ skip if already done ! (PM) }
|
|
||||||
if not assigned(t.resulttype.def) or
|
|
||||||
(t.resulttype.def^.deftype<>arraydef) or
|
|
||||||
not parraydef(t.resulttype.def)^.IsConstructor or
|
|
||||||
(parraydef(t.resulttype.def)^.lowrange<>0) or
|
|
||||||
(parraydef(t.resulttype.def)^.highrange<>len-1) then
|
|
||||||
t.resulttype.setdef(new(parraydef,init(0,len-1,s32bittype)));
|
|
||||||
|
|
||||||
parraydef(t.resulttype.def)^.elementtype:=htype;
|
|
||||||
parraydef(t.resulttype.def)^.IsConstructor:=true;
|
|
||||||
parraydef(t.resulttype.def)^.IsVariant:=varia;
|
|
||||||
t.location.loc:=LOC_MEM;
|
|
||||||
end;
|
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
{ only pass left tree, right tree contains next construct if any }
|
{ only pass left tree, right tree contains next construct if any }
|
||||||
htype:=constructortype;
|
|
||||||
len:=0;
|
|
||||||
varia:=false;
|
|
||||||
if assigned(left) then
|
if assigned(left) then
|
||||||
begin
|
begin
|
||||||
hp:=self;
|
hp:=self;
|
||||||
@ -633,8 +612,8 @@ implementation
|
|||||||
begin
|
begin
|
||||||
firstpass(hp.left);
|
firstpass(hp.left);
|
||||||
set_varstate(hp.left,true);
|
set_varstate(hp.left,true);
|
||||||
if (not get_para_resulttype) and
|
{ Insert typeconvs for array of const }
|
||||||
(not(nf_novariaallowed in flags)) then
|
if parraydef(resulttype.def)^.IsVariant then
|
||||||
begin
|
begin
|
||||||
case hp.left.resulttype.def^.deftype of
|
case hp.left.resulttype.def^.deftype of
|
||||||
enumdef :
|
enumdef :
|
||||||
@ -676,23 +655,6 @@ implementation
|
|||||||
CGMessagePos1(hp.left.fileinfo,type_e_wrong_type_in_array_constructor,hp.left.resulttype.def^.typename);
|
CGMessagePos1(hp.left.fileinfo,type_e_wrong_type_in_array_constructor,hp.left.resulttype.def^.typename);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if (htype.def=nil) then
|
|
||||||
htype:=hp.left.resulttype
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
if ((nf_novariaallowed in flags) or (not varia)) and
|
|
||||||
(not is_equal(htype.def,hp.left.resulttype.def)) then
|
|
||||||
begin
|
|
||||||
{ if both should be equal try inserting a conversion }
|
|
||||||
if nf_novariaallowed in flags then
|
|
||||||
begin
|
|
||||||
hp.left:=ctypeconvnode.create(hp.left,htype);
|
|
||||||
firstpass(hp.left);
|
|
||||||
end;
|
|
||||||
varia:=true;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
inc(len);
|
|
||||||
hp:=tarrayconstructornode(hp.right);
|
hp:=tarrayconstructornode(hp.right);
|
||||||
end;
|
end;
|
||||||
{ swap the tree for cargs }
|
{ swap the tree for cargs }
|
||||||
@ -711,14 +673,17 @@ implementation
|
|||||||
end;
|
end;
|
||||||
include(chp.flags,nf_cargs);
|
include(chp.flags,nf_cargs);
|
||||||
include(chp.flags,nf_cargswap);
|
include(chp.flags,nf_cargswap);
|
||||||
postprocess(chp);
|
calcregisters(chp,0,0,0);
|
||||||
|
chp.location.loc:=LOC_MEM;
|
||||||
result:=chp;
|
result:=chp;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
postprocess(self);
|
calcregisters(self,0,0,0);
|
||||||
|
location.loc:=LOC_MEM;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function tarrayconstructornode.docompare(p: tnode): boolean;
|
function tarrayconstructornode.docompare(p: tnode): boolean;
|
||||||
begin
|
begin
|
||||||
docompare :=
|
docompare :=
|
||||||
@ -732,23 +697,25 @@ implementation
|
|||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
constructor ttypenode.create(t : ttype);
|
constructor ttypenode.create(t : ttype);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
inherited create(typen);
|
inherited create(typen);
|
||||||
restype:=t;
|
restype:=t;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ttypenode.det_resulttype:tnode;
|
function ttypenode.det_resulttype:tnode;
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
resulttype:=restype;
|
resulttype:=restype;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ttypenode.pass_1 : tnode;
|
function ttypenode.pass_1 : tnode;
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ttypenode.docompare(p: tnode): boolean;
|
function ttypenode.docompare(p: tnode): boolean;
|
||||||
begin
|
begin
|
||||||
docompare :=
|
docompare :=
|
||||||
@ -765,7 +732,10 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.11 2001-04-02 21:20:31 peter
|
Revision 1.12 2001-04-04 22:42:40 peter
|
||||||
|
* move constant folding into det_resulttype
|
||||||
|
|
||||||
|
Revision 1.11 2001/04/02 21:20:31 peter
|
||||||
* resulttype rewrite
|
* resulttype rewrite
|
||||||
|
|
||||||
Revision 1.10 2000/12/31 11:14:10 jonas
|
Revision 1.10 2000/12/31 11:14:10 jonas
|
||||||
|
@ -83,6 +83,7 @@ implementation
|
|||||||
var
|
var
|
||||||
t : tnode;
|
t : tnode;
|
||||||
rd,ld : pdef;
|
rd,ld : pdef;
|
||||||
|
rv,lv : tconstexprint;
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
resulttypepass(left);
|
resulttypepass(left);
|
||||||
@ -92,6 +93,31 @@ implementation
|
|||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
{ constant folding }
|
||||||
|
if is_constintnode(left) and is_constintnode(right) then
|
||||||
|
begin
|
||||||
|
rv:=tordconstnode(right).value;
|
||||||
|
lv:=tordconstnode(left).value;
|
||||||
|
|
||||||
|
{ check for division by zero }
|
||||||
|
if (rv=0) then
|
||||||
|
begin
|
||||||
|
Message(parser_e_division_by_zero);
|
||||||
|
{ recover }
|
||||||
|
rv:=1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
case nodetype of
|
||||||
|
modn:
|
||||||
|
t:=genintconstnode(lv mod rv);
|
||||||
|
divn:
|
||||||
|
t:=genintconstnode(lv div rv);
|
||||||
|
end;
|
||||||
|
resulttypepass(t);
|
||||||
|
result:=t;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
{ allow operator overloading }
|
{ allow operator overloading }
|
||||||
t:=self;
|
t:=self;
|
||||||
if isbinaryoverloaded(t) then
|
if isbinaryoverloaded(t) then
|
||||||
@ -166,8 +192,6 @@ implementation
|
|||||||
function tmoddivnode.pass_1 : tnode;
|
function tmoddivnode.pass_1 : tnode;
|
||||||
var
|
var
|
||||||
t : tnode;
|
t : tnode;
|
||||||
rv,lv : tconstexprint;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
firstpass(left);
|
firstpass(left);
|
||||||
@ -175,30 +199,6 @@ implementation
|
|||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
if is_constintnode(left) and is_constintnode(right) then
|
|
||||||
begin
|
|
||||||
rv:=tordconstnode(right).value;
|
|
||||||
lv:=tordconstnode(left).value;
|
|
||||||
|
|
||||||
{ check for division by zero }
|
|
||||||
if (rv=0) then
|
|
||||||
begin
|
|
||||||
Message(parser_e_division_by_zero);
|
|
||||||
{ recover }
|
|
||||||
rv:=1;
|
|
||||||
end;
|
|
||||||
|
|
||||||
case nodetype of
|
|
||||||
modn:
|
|
||||||
t:=genintconstnode(lv mod rv);
|
|
||||||
divn:
|
|
||||||
t:=genintconstnode(lv div rv);
|
|
||||||
end;
|
|
||||||
firstpass(t);
|
|
||||||
result:=t;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ 64bit }
|
{ 64bit }
|
||||||
if (left.resulttype.def^.deftype=orddef) and (right.resulttype.def^.deftype=orddef) and
|
if (left.resulttype.def^.deftype=orddef) and (right.resulttype.def^.deftype=orddef) and
|
||||||
(is_64bitint(left.resulttype.def) or is_64bitint(right.resulttype.def)) then
|
(is_64bitint(left.resulttype.def) or is_64bitint(right.resulttype.def)) then
|
||||||
@ -232,6 +232,20 @@ implementation
|
|||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
{ constant folding }
|
||||||
|
if is_constintnode(left) and is_constintnode(right) then
|
||||||
|
begin
|
||||||
|
case nodetype of
|
||||||
|
shrn:
|
||||||
|
t:=genintconstnode(tordconstnode(left).value shr tordconstnode(right).value);
|
||||||
|
shln:
|
||||||
|
t:=genintconstnode(tordconstnode(left).value shl tordconstnode(right).value);
|
||||||
|
end;
|
||||||
|
resulttypepass(t);
|
||||||
|
result:=t;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
{ allow operator overloading }
|
{ allow operator overloading }
|
||||||
t:=self;
|
t:=self;
|
||||||
if isbinaryoverloaded(t) then
|
if isbinaryoverloaded(t) then
|
||||||
@ -265,19 +279,6 @@ implementation
|
|||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
if is_constintnode(left) and is_constintnode(right) then
|
|
||||||
begin
|
|
||||||
case nodetype of
|
|
||||||
shrn:
|
|
||||||
t:=genintconstnode(tordconstnode(left).value shr tordconstnode(right).value);
|
|
||||||
shln:
|
|
||||||
t:=genintconstnode(tordconstnode(left).value shl tordconstnode(right).value);
|
|
||||||
end;
|
|
||||||
firstpass(t);
|
|
||||||
result:=t;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ 64 bit ints have their own shift handling }
|
{ 64 bit ints have their own shift handling }
|
||||||
if not(is_64bitint(left.resulttype.def)) then
|
if not(is_64bitint(left.resulttype.def)) then
|
||||||
regs:=1
|
regs:=1
|
||||||
@ -311,8 +312,24 @@ implementation
|
|||||||
set_varstate(left,true);
|
set_varstate(left,true);
|
||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
resulttype:=left.resulttype;
|
|
||||||
|
|
||||||
|
{ constant folding }
|
||||||
|
if is_constintnode(left) then
|
||||||
|
begin
|
||||||
|
tordconstnode(left).value:=-tordconstnode(left).value;
|
||||||
|
result:=left;
|
||||||
|
left:=nil;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if is_constrealnode(left) then
|
||||||
|
begin
|
||||||
|
trealconstnode(left).value_real:=-trealconstnode(left).value_real;
|
||||||
|
result:=left;
|
||||||
|
left:=nil;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
resulttype:=left.resulttype;
|
||||||
if (left.resulttype.def^.deftype=floatdef) then
|
if (left.resulttype.def^.deftype=floatdef) then
|
||||||
begin
|
begin
|
||||||
end
|
end
|
||||||
@ -371,21 +388,6 @@ implementation
|
|||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
if is_constintnode(left) then
|
|
||||||
begin
|
|
||||||
t:=cordconstnode.create(-tordconstnode(left).value,resulttype);
|
|
||||||
firstpass(t);
|
|
||||||
result:=t;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
if is_constrealnode(left) then
|
|
||||||
begin
|
|
||||||
t:=crealconstnode.create(-trealconstnode(left).value_real,resulttype);
|
|
||||||
firstpass(t);
|
|
||||||
result:=t;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
registers32:=left.registers32;
|
registers32:=left.registers32;
|
||||||
registersfpu:=left.registersfpu;
|
registersfpu:=left.registersfpu;
|
||||||
{$ifdef SUPPORT_MMX}
|
{$ifdef SUPPORT_MMX}
|
||||||
@ -436,6 +438,7 @@ implementation
|
|||||||
var
|
var
|
||||||
t : tnode;
|
t : tnode;
|
||||||
notdef : pprocdef;
|
notdef : pprocdef;
|
||||||
|
v : tconstexprint;
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
resulttypepass(left);
|
resulttypepass(left);
|
||||||
@ -443,6 +446,29 @@ implementation
|
|||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
{ constant folding }
|
||||||
|
if (left.nodetype=ordconstn) then
|
||||||
|
begin
|
||||||
|
if is_boolean(left.resulttype.def) then
|
||||||
|
{ here we do a boolean(byte(..)) type cast because }
|
||||||
|
{ boolean(<int64>) is buggy in 1.00 }
|
||||||
|
t:=cordconstnode.create(byte(not(boolean(byte(tordconstnode(left).value)))),left.resulttype)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
v:=tordconstnode(left).value;
|
||||||
|
case left.resulttype.def^.size of
|
||||||
|
1 : v:=(not(v and $ff)) and $ff;
|
||||||
|
2 : v:=(not(v and $ffff)) and $ffff;
|
||||||
|
4 : v:=(not(v and $ffffffff)) and $ffffffff;
|
||||||
|
8 : v:=not(v);
|
||||||
|
end;
|
||||||
|
t:=cordconstnode.create(v,left.resulttype);
|
||||||
|
end;
|
||||||
|
resulttypepass(t);
|
||||||
|
result:=t;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
resulttype:=left.resulttype;
|
resulttype:=left.resulttype;
|
||||||
if is_boolean(resulttype.def) then
|
if is_boolean(resulttype.def) then
|
||||||
begin
|
begin
|
||||||
@ -460,8 +486,6 @@ implementation
|
|||||||
end
|
end
|
||||||
else if is_integer(left.resulttype.def) then
|
else if is_integer(left.resulttype.def) then
|
||||||
begin
|
begin
|
||||||
if (porddef(left.resulttype.def)^.typ <> u32bit) then
|
|
||||||
inserttypeconv(left,s32bittype);
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -494,25 +518,10 @@ implementation
|
|||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
firstpass(left);
|
firstpass(left);
|
||||||
set_varstate(left,true);
|
|
||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
if (left.nodetype=ordconstn) then
|
|
||||||
begin
|
|
||||||
if is_boolean(left.resulttype.def) then
|
|
||||||
{ here we do a boolena(byte(..)) type cast because }
|
|
||||||
{ boolean(<int64>) is buggy in 1.00 }
|
|
||||||
t:=cordconstnode.create(byte(not(boolean(byte(tordconstnode(left).value)))),left.resulttype)
|
|
||||||
else
|
|
||||||
t:=cordconstnode.create(not(tordconstnode(left).value),left.resulttype);
|
|
||||||
firstpass(t);
|
|
||||||
result:=t;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
location.loc:=left.location.loc;
|
location.loc:=left.location.loc;
|
||||||
resulttype:=left.resulttype;
|
|
||||||
registers32:=left.registers32;
|
registers32:=left.registers32;
|
||||||
{$ifdef SUPPORT_MMX}
|
{$ifdef SUPPORT_MMX}
|
||||||
registersmmx:=left.registersmmx;
|
registersmmx:=left.registersmmx;
|
||||||
@ -569,7 +578,10 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.17 2001-04-02 21:20:31 peter
|
Revision 1.18 2001-04-04 22:42:40 peter
|
||||||
|
* move constant folding into det_resulttype
|
||||||
|
|
||||||
|
Revision 1.17 2001/04/02 21:20:31 peter
|
||||||
* resulttype rewrite
|
* resulttype rewrite
|
||||||
|
|
||||||
Revision 1.16 2001/03/20 18:11:03 jonas
|
Revision 1.16 2001/03/20 18:11:03 jonas
|
||||||
|
Loading…
Reference in New Issue
Block a user