mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 16:09:17 +02:00
compiler: further improve preprocessor evaluator:
* support TRUE,FALSE for all modes * refactor texprvalue.evaluate to support arithmetic expressions and implement them here * simplify read_expr and read_factor code git-svn-id: trunk@25463 -
This commit is contained in:
parent
cac09f9df1
commit
7ecaaf0ef8
@ -814,6 +814,7 @@ type
|
|||||||
def: tdef;
|
def: tdef;
|
||||||
constructor create_const(c:tconstsym);
|
constructor create_const(c:tconstsym);
|
||||||
constructor create_error;
|
constructor create_error;
|
||||||
|
constructor create_ord(v: Tconstexprint);
|
||||||
constructor create_int(v: int64);
|
constructor create_int(v: int64);
|
||||||
constructor create_uint(v: qword);
|
constructor create_uint(v: qword);
|
||||||
constructor create_bool(b: boolean);
|
constructor create_bool(b: boolean);
|
||||||
@ -822,7 +823,7 @@ type
|
|||||||
constructor create_real(r: bestreal);
|
constructor create_real(r: bestreal);
|
||||||
class function try_parse_number(s:string):texprvalue; static;
|
class function try_parse_number(s:string):texprvalue; static;
|
||||||
class function try_parse_real(s:string):texprvalue; static;
|
class function try_parse_real(s:string):texprvalue; static;
|
||||||
function evaluate(v:texprvalue;op:ttoken): boolean;
|
function evaluate(v:texprvalue;op:ttoken):texprvalue;
|
||||||
procedure error(expecteddef, place: string);
|
procedure error(expecteddef, place: string);
|
||||||
function asBool: Boolean;
|
function asBool: Boolean;
|
||||||
function asInt: Integer;
|
function asInt: Integer;
|
||||||
@ -894,6 +895,17 @@ type
|
|||||||
def:=generrordef;
|
def:=generrordef;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
constructor texprvalue.create_ord(v: Tconstexprint);
|
||||||
|
begin
|
||||||
|
fillchar(value,sizeof(value),#0);
|
||||||
|
consttyp:=constord;
|
||||||
|
value.valueord:=v;
|
||||||
|
if v.signed then
|
||||||
|
def:=sintdef
|
||||||
|
else
|
||||||
|
def:=uintdef;
|
||||||
|
end;
|
||||||
|
|
||||||
constructor texprvalue.create_int(v: int64);
|
constructor texprvalue.create_int(v: int64);
|
||||||
begin
|
begin
|
||||||
fillchar(value,sizeof(value),#0);
|
fillchar(value,sizeof(value),#0);
|
||||||
@ -984,7 +996,7 @@ type
|
|||||||
result:=nil;
|
result:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function texprvalue.evaluate(v:texprvalue;op:ttoken): boolean;
|
function texprvalue.evaluate(v:texprvalue;op:ttoken):texprvalue;
|
||||||
|
|
||||||
function check_compatbile: boolean;
|
function check_compatbile: boolean;
|
||||||
begin
|
begin
|
||||||
@ -994,103 +1006,138 @@ type
|
|||||||
) or
|
) or
|
||||||
(is_string(v.def) and is_string(def));
|
(is_string(v.def) and is_string(def));
|
||||||
if not result then
|
if not result then
|
||||||
incompatibletypes(def,v.def);
|
Message2(type_e_incompatible_types,def.typename,v.def.typename);
|
||||||
end;
|
end;
|
||||||
var
|
var
|
||||||
lv,rv: tconstexprint;
|
lv,rv: tconstexprint;
|
||||||
lvd,rvd: bestreal;
|
lvd,rvd: bestreal;
|
||||||
lvs,rvs: string;
|
lvs,rvs: string;
|
||||||
begin
|
begin
|
||||||
if op = _IN then
|
case op of
|
||||||
|
_IN:
|
||||||
begin
|
begin
|
||||||
if not is_set(v.def) then
|
if not is_set(v.def) then
|
||||||
begin
|
begin
|
||||||
v.error('set', 'IN');
|
v.error('Set', 'IN');
|
||||||
result:=false;
|
result:=texprvalue.create_error;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if not is_ordinal(def) then
|
if not is_ordinal(def) then
|
||||||
begin
|
begin
|
||||||
error('ordinal', 'IN');
|
error('Ordinal', 'IN');
|
||||||
result:=false;
|
result:=texprvalue.create_error;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if value.valueord.signed then
|
if value.valueord.signed then
|
||||||
result:=value.valueord.svalue in pnormalset(v.value.valueptr)^
|
result:=texprvalue.create_bool(value.valueord.svalue in pnormalset(v.value.valueptr)^)
|
||||||
else
|
else
|
||||||
result:=value.valueord.uvalue in pnormalset(v.value.valueptr)^;
|
result:=texprvalue.create_bool(value.valueord.uvalue in pnormalset(v.value.valueptr)^);
|
||||||
end
|
end;
|
||||||
else
|
_OP_NOT:
|
||||||
if check_compatbile then
|
|
||||||
begin
|
begin
|
||||||
if (is_ordinal(def) and is_ordinal(v.def)) then
|
if is_boolean(def) then
|
||||||
begin
|
result:=texprvalue.create_bool(not asBool)
|
||||||
lv:=value.valueord;
|
|
||||||
rv:=v.value.valueord;
|
|
||||||
case op of
|
|
||||||
_EQ:
|
|
||||||
result:=lv=rv;
|
|
||||||
_NE:
|
|
||||||
result:=lv<>rv;
|
|
||||||
_LT:
|
|
||||||
result:=lv<rv;
|
|
||||||
_GT:
|
|
||||||
result:=lv>rv;
|
|
||||||
_GTE:
|
|
||||||
result:=lv>=rv;
|
|
||||||
_LTE:
|
|
||||||
result:=lv<=rv;
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
if (is_fpu(def) or is_ordinal(def)) and
|
|
||||||
(is_fpu(v.def) or is_ordinal(v.def)) then
|
|
||||||
begin
|
begin
|
||||||
if is_fpu(def) then
|
error('Boolean', 'NOT');
|
||||||
lvd:=pbestreal(value.valueptr)^
|
result:=texprvalue.create_error;
|
||||||
else
|
|
||||||
lvd:=value.valueord;
|
|
||||||
if is_fpu(v.def) then
|
|
||||||
rvd:=pbestreal(v.value.valueptr)^
|
|
||||||
else
|
|
||||||
rvd:=v.value.valueord;
|
|
||||||
case op of
|
|
||||||
_EQ:
|
|
||||||
result:=lvd=rvd;
|
|
||||||
_NE:
|
|
||||||
result:=lvd<>rvd;
|
|
||||||
_LT:
|
|
||||||
result:=lvd<rvd;
|
|
||||||
_GT:
|
|
||||||
result:=lvd>rvd;
|
|
||||||
_GTE:
|
|
||||||
result:=lvd>=rvd;
|
|
||||||
_LTE:
|
|
||||||
result:=lvd<=rvd;
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
lvs:=asStr;
|
|
||||||
rvs:=v.asStr;
|
|
||||||
case op of
|
|
||||||
_EQ:
|
|
||||||
result:=lvs=rvs;
|
|
||||||
_NE:
|
|
||||||
result:=lvs<>rvs;
|
|
||||||
_LT:
|
|
||||||
result:=lvs<rvs;
|
|
||||||
_GT:
|
|
||||||
result:=lvs>rvs;
|
|
||||||
_GTE:
|
|
||||||
result:=lvs>=rvs;
|
|
||||||
_LTE:
|
|
||||||
result:=lvs<=rvs;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end
|
_EQ,_NE,_LT,_GT,_GTE,_LTE,_PLUS,_MINUS,_STAR,_SLASH:
|
||||||
else
|
if check_compatbile then
|
||||||
result:=false;
|
begin
|
||||||
|
if (is_ordinal(def) and is_ordinal(v.def)) then
|
||||||
|
begin
|
||||||
|
lv:=value.valueord;
|
||||||
|
rv:=v.value.valueord;
|
||||||
|
case op of
|
||||||
|
_EQ:
|
||||||
|
result:=texprvalue.create_bool(lv=rv);
|
||||||
|
_NE:
|
||||||
|
result:=texprvalue.create_bool(lv<>rv);
|
||||||
|
_LT:
|
||||||
|
result:=texprvalue.create_bool(lv<rv);
|
||||||
|
_GT:
|
||||||
|
result:=texprvalue.create_bool(lv>rv);
|
||||||
|
_GTE:
|
||||||
|
result:=texprvalue.create_bool(lv>=rv);
|
||||||
|
_LTE:
|
||||||
|
result:=texprvalue.create_bool(lv<=rv);
|
||||||
|
_PLUS:
|
||||||
|
result:=texprvalue.create_ord(lv+rv);
|
||||||
|
_MINUS:
|
||||||
|
result:=texprvalue.create_ord(lv-rv);
|
||||||
|
_STAR:
|
||||||
|
result:=texprvalue.create_ord(lv*rv);
|
||||||
|
_SLASH:
|
||||||
|
result:=texprvalue.create_real(lv/rv);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (is_fpu(def) or is_ordinal(def)) and
|
||||||
|
(is_fpu(v.def) or is_ordinal(v.def)) then
|
||||||
|
begin
|
||||||
|
if is_fpu(def) then
|
||||||
|
lvd:=pbestreal(value.valueptr)^
|
||||||
|
else
|
||||||
|
lvd:=value.valueord;
|
||||||
|
if is_fpu(v.def) then
|
||||||
|
rvd:=pbestreal(v.value.valueptr)^
|
||||||
|
else
|
||||||
|
rvd:=v.value.valueord;
|
||||||
|
case op of
|
||||||
|
_EQ:
|
||||||
|
result:=texprvalue.create_bool(lvd=rvd);
|
||||||
|
_NE:
|
||||||
|
result:=texprvalue.create_bool(lvd<>rvd);
|
||||||
|
_LT:
|
||||||
|
result:=texprvalue.create_bool(lvd<rvd);
|
||||||
|
_GT:
|
||||||
|
result:=texprvalue.create_bool(lvd>rvd);
|
||||||
|
_GTE:
|
||||||
|
result:=texprvalue.create_bool(lvd>=rvd);
|
||||||
|
_LTE:
|
||||||
|
result:=texprvalue.create_bool(lvd<=rvd);
|
||||||
|
_PLUS:
|
||||||
|
result:=texprvalue.create_real(lvd+rvd);
|
||||||
|
_MINUS:
|
||||||
|
result:=texprvalue.create_real(lvd-rvd);
|
||||||
|
_STAR:
|
||||||
|
result:=texprvalue.create_real(lvd*rvd);
|
||||||
|
_SLASH:
|
||||||
|
result:=texprvalue.create_real(lvd/rvd);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
lvs:=asStr;
|
||||||
|
rvs:=v.asStr;
|
||||||
|
case op of
|
||||||
|
_EQ:
|
||||||
|
result:=texprvalue.create_bool(lvs=rvs);
|
||||||
|
_NE:
|
||||||
|
result:=texprvalue.create_bool(lvs<>rvs);
|
||||||
|
_LT:
|
||||||
|
result:=texprvalue.create_bool(lvs<rvs);
|
||||||
|
_GT:
|
||||||
|
result:=texprvalue.create_bool(lvs>rvs);
|
||||||
|
_GTE:
|
||||||
|
result:=texprvalue.create_bool(lvs>=rvs);
|
||||||
|
_LTE:
|
||||||
|
result:=texprvalue.create_bool(lvs<=rvs);
|
||||||
|
_PLUS:
|
||||||
|
result:=texprvalue.create_str(lvs+rvs);
|
||||||
|
_MINUS, _STAR, _SLASH:
|
||||||
|
begin
|
||||||
|
Message(parser_e_illegal_expression);
|
||||||
|
result:=texprvalue.create_error;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result:=texprvalue.create_error;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure texprvalue.error(expecteddef, place: string);
|
procedure texprvalue.error(expecteddef, place: string);
|
||||||
@ -1375,9 +1422,9 @@ type
|
|||||||
result:=texprvalue.try_parse_number(pp);
|
result:=texprvalue.try_parse_number(pp);
|
||||||
if not assigned(result) then
|
if not assigned(result) then
|
||||||
begin
|
begin
|
||||||
if assigned(mac) and (m_mac in current_settings.modeswitches) and (pp='FALSE') then
|
if assigned(mac) and (pp='FALSE') then
|
||||||
result:=texprvalue.create_bool(false)
|
result:=texprvalue.create_bool(false)
|
||||||
else if assigned(mac) and (m_mac in current_settings.modeswitches) and (pp='TRUE') then
|
else if assigned(mac) and (pp='TRUE') then
|
||||||
result:=texprvalue.create_bool(true)
|
result:=texprvalue.create_bool(true)
|
||||||
else if (m_mac in current_settings.modeswitches) and
|
else if (m_mac in current_settings.modeswitches) and
|
||||||
(not assigned(mac) or not mac.defined) and
|
(not assigned(mac) or not mac.defined) and
|
||||||
@ -1691,24 +1738,19 @@ type
|
|||||||
preproc_consume(_ID);
|
preproc_consume(_ID);
|
||||||
exprvalue:=read_factor(eval);
|
exprvalue:=read_factor(eval);
|
||||||
if eval then
|
if eval then
|
||||||
begin
|
result:=exprvalue.evaluate(nil,_OP_NOT)
|
||||||
if is_boolean(exprvalue.def) then
|
|
||||||
result:=texprvalue.create_bool(not exprvalue.asBool)
|
|
||||||
else
|
|
||||||
exprvalue.error('Boolean', 'NOT');
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
result:=texprvalue.create_bool(false); {Just to have something}
|
result:=texprvalue.create_bool(false); {Just to have something}
|
||||||
exprvalue.free;
|
exprvalue.free;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if (m_mac in current_settings.modeswitches) and (current_scanner.preproc_pattern='TRUE') then
|
if (current_scanner.preproc_pattern='TRUE') then
|
||||||
begin
|
begin
|
||||||
result:=texprvalue.create_bool(true);
|
result:=texprvalue.create_bool(true);
|
||||||
preproc_consume(_ID);
|
preproc_consume(_ID);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if (m_mac in current_settings.modeswitches) and (current_scanner.preproc_pattern='FALSE') then
|
if (current_scanner.preproc_pattern='FALSE') then
|
||||||
begin
|
begin
|
||||||
result:=texprvalue.create_bool(false);
|
result:=texprvalue.create_bool(false);
|
||||||
preproc_consume(_ID);
|
preproc_consume(_ID);
|
||||||
@ -1871,8 +1913,7 @@ type
|
|||||||
function read_expr(eval:Boolean): texprvalue;
|
function read_expr(eval:Boolean): texprvalue;
|
||||||
var
|
var
|
||||||
hs1,hs2: texprvalue;
|
hs1,hs2: texprvalue;
|
||||||
b : boolean;
|
op: ttoken;
|
||||||
op : ttoken;
|
|
||||||
begin
|
begin
|
||||||
hs1:=read_simple_expr(eval);
|
hs1:=read_simple_expr(eval);
|
||||||
op:=current_scanner.preproc_token;
|
op:=current_scanner.preproc_token;
|
||||||
@ -1891,14 +1932,12 @@ type
|
|||||||
hs2:=read_simple_expr(eval);
|
hs2:=read_simple_expr(eval);
|
||||||
|
|
||||||
if eval then
|
if eval then
|
||||||
b:=hs1.evaluate(hs2,op)
|
result:=hs1.evaluate(hs2,op)
|
||||||
else
|
else
|
||||||
b:= false; {Just to have something}
|
result:=texprvalue.create_bool(false); {Just to have something}
|
||||||
|
|
||||||
hs1.free;
|
hs1.free;
|
||||||
hs2.free;
|
hs2.free;
|
||||||
|
|
||||||
result:=texprvalue.create_bool(b);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
Loading…
Reference in New Issue
Block a user