Distinguish the different types of floating-point constants.

As with expressions, the type does not actually limit the precision and range of values represented.
This commit is contained in:
Stephen Heumann 2021-03-07 00:48:51 -06:00
parent 41623529d7
commit 8f8e7f12e2
5 changed files with 81 additions and 21 deletions

View File

@ -168,7 +168,7 @@ type
ident, {identifiers}
{constants}
intconst,uintconst,longconst,ulongconst,longlongconst,
ulonglongconst,extendedconst,
ulonglongconst,floatconst,doubleconst,extendedconst,compconst,
stringconst,
{reserved words}
_Alignassy,_Alignofsy,_Atomicsy,_Boolsy,_Complexsy,

View File

@ -1477,14 +1477,26 @@ var
end; {if}
if op^.right^.token.kind in [intconst,uintconst,longconst,ulongconst,
longlongconst,ulonglongconst,extendedconst] then
longlongconst,ulonglongconst,floatconst,doubleconst,extendedconst,
compconst] then
if op^.left^.token.kind in [intconst,uintconst,longconst,ulongconst,
longlongconst,ulonglongconst,extendedconst] then
longlongconst,ulonglongconst,floatconst,doubleconst,extendedconst,
compconst] then
begin
if fenvAccess then
if kind in [normalExpression, autoInitializerExpression] then
goto 1;
ekind := extendedconst; {evaluate a constant operation}
if (op^.right^.token.kind = compConst)
and (op^.left^.token.kind = compConst) then
ekind := compconst
else if (op^.right^.token.kind in [extendedConst,compConst])
or (op^.left^.token.kind in [extendedConst,compConst]) then
ekind := extendedconst
else if (op^.right^.token.kind = doubleConst)
or (op^.left^.token.kind = doubleConst) then
ekind := doubleconst
else
ekind := floatconst;
rop1 := RealVal(op^.left^.token);
rop2 := RealVal(op^.right^.token);
dispose(op^.right);
@ -1539,7 +1551,7 @@ var
else begin
op^.token.rval := rop1;
op^.token.class := realConstant;
op^.token.kind := extendedConst;
op^.token.kind := ekind;
end; {else}
end; {if}
1:
@ -1665,7 +1677,12 @@ var
op^.token.qval := llop1;
end {else if}
else begin
op^.token.kind := extendedConst;
case baseType of
cgReal: op^.token.kind := floatConst;
cgDouble: op^.token.kind := doubleConst;
cgExtended: op^.token.kind := extendedConst;
cgComp: op^.token.kind := compConst;
end; {case}
op^.token.class := realConstant;
LimitPrecision(rop1, baseType);
op^.token.rval := rop1;
@ -1745,18 +1762,19 @@ var
op^.token.ival := long(op1).lsw;
end; {else}
end {else if}
else if op^.left^.token.kind = extendedconst then begin
else if op^.left^.token.kind in
[floatconst,doubleconst,extendedconst,compconst] then begin
if fenvAccess then
if kind in [normalExpression, autoInitializerExpression] then
goto 4;
ekind := extendedconst; {evaluate a constant operation}
ekind := op^.left^.token.kind;
rop1 := RealVal(op^.left^.token);
dispose(op^.left);
op^.left := nil;
case op^.token.kind of
uminus : begin {unary -}
op^.token.class := realConstant;
op^.token.kind := extendedConst;
op^.token.kind := ekind;
op^.token.rval := -rop1;
end;
excch : begin {!}
@ -1767,7 +1785,7 @@ var
otherwise : begin {illegal operation}
Error(66);
op^.token.class := realConstant;
op^.token.kind := extendedConst;
op^.token.kind := ekind;
op^.token.rval := rop1;
end;
end; {case}
@ -1834,10 +1852,11 @@ if token.kind in startExpression then begin
sp^.right := nil;
stack := sp;
if kind in [preprocessorExpression,arrayExpression] then
if token.kind in [stringconst,extendedconst] then begin
if token.kind in [stringconst,floatconst,doubleconst,
extendedconst,compconst] then begin
if kind = arrayExpression then begin
op := opStack;
if token.kind = extendedconst then
if token.kind <> stringconst then
if op <> nil then
if op^.token.kind = castoper then
if op^.casttype^.kind = scalarType then
@ -3292,11 +3311,26 @@ case tree^.token.kind of
end; {if}
end; {case longlongConst}
extendedConst: begin
floatConst: begin
GenLdcReal(tree^.token.rval);
expressionType := floatPtr;
end; {case floatConst}
doubleConst: begin
GenLdcReal(tree^.token.rval);
expressionType := doublePtr;
end; {case doubleConst}
extendedConst: begin
GenLdcReal(tree^.token.rval);
expressionType := extendedPtr;
end; {case extendedConst}
compConst: begin
GenLdcReal(tree^.token.rval);
expressionType := compPtr;
end; {case compConst}
stringConst: begin
GenS(pc_lca, tree^.token.sval);
expressionType := stringTypePtr;
@ -4417,9 +4451,17 @@ else begin {record the expression for an initialize
expressionType := ulongLongPtr;
isConstant := true;
end {else if}
else if tree^.token.kind = extendedconst then begin
else if tree^.token.kind in
[floatconst,doubleconst,extendedconst,compconst] then begin
realExpressionValue := tree^.token.rval;
expressionType := extendedPtr;
if tree^.token.kind = extendedconst then
expressionType := extendedPtr
else if tree^.token.kind = doubleconst then
expressionType := doublePtr
else if tree^.token.kind = floatconst then
expressionType := floatPtr
else {if tree^.token.kind = compconst then}
expressionType := compPtr;
isConstant := true;
if kind in [arrayExpression,preprocessorExpression] then begin
expressionType := intPtr;
@ -4472,7 +4514,8 @@ procedure InitExpression;
begin {InitExpression}
startTerm := [ident,intconst,uintconst,longconst,ulongconst,longlongconst,
ulonglongconst,extendedconst,stringconst,_Genericsy];
ulonglongconst,floatconst,doubleconst,extendedconst,compconst,
stringconst,_Genericsy];
startExpression:= startTerm +
[lparench,asteriskch,andch,plusch,minusch,excch,tildech,sizeofsy,
plusplusop,minusminusop,typedef,_Alignofsy];

View File

@ -18,7 +18,7 @@ uses CCommon, MM, Scanner, Symbol, CGI;
{$segment 'SCANNER'}
const
symFileVersion = 12; {version number of .sym file format}
symFileVersion = 13; {version number of .sym file format}
var
inhibitHeader: boolean; {should .sym includes be blocked?}
@ -1341,7 +1341,7 @@ var
token.qval.lo := ReadLong;
token.qval.hi := ReadLong;
end;
realConstant: token.rval := ReadExtended;
realConstant: token.rval := ReadExtended;
stringConstant: begin
token.sval := ReadLongString;
token.ispstring := ReadByte <> 0;

View File

@ -756,6 +756,9 @@ case token.kind of
longlongConst,
ulonglongConst: write('0x...'); {TODO implement}
compConst,
floatConst,
doubleConst,
extendedConst: write(token.rval:1);
stringConst: begin
@ -3229,6 +3232,7 @@ var
isHex: boolean; {is the value a hex number?}
isLong: boolean; {is the value a long number?}
isLongLong: boolean; {is the value a long long number?}
isFloat: boolean; {is the value a number of type float?}
isReal: boolean; {is the value a real number?}
numIndex: 0..maxLine; {index into workString}
sp: stringPtr; {for saving identifier names}
@ -3320,6 +3324,7 @@ isHex := false; {assume it's not hex}
isReal := false; {assume it's an integer}
isLong := false; {assume a short integer}
isLongLong := false;
isFloat := false;
unsigned := false; {assume signed numbers}
stringIndex := 0; {no digits so far...}
if scanWork then begin {set up the scanner}
@ -3408,13 +3413,19 @@ if c2 in ['f','F'] then begin {allow F designator on reals}
FlagError(100);
isReal := true;
end; {if}
isFloat := true;
NextChar;
end; {if}
numString[0] := chr(stringIndex); {set the length of the string}
if doingPPExpression then
isLongLong := true;
if isReal then begin {convert a real constant}
token.kind := extendedConst;
if isFloat then
token.kind := floatConst
else if isLong then
token.kind := extendedConst
else
token.kind := doubleConst;
token.class := realConstant;
if stringIndex > 80 then begin
FlagError(131);

View File

@ -285,7 +285,7 @@ charSym start single character symbols
enum ident,0 identifiers
! constants
enum (intconst,uintconst,longconst,ulongconst,longlongconst)
enum (ulonglongconst,extendedconst)
enum (ulonglongconst,floatconst,doubleconst,extendedconst,compconst)
enum stringconst
! reserved words
enum (_Alignassy,_Alignofsy,_Atomicsy,_Boolsy,_Complexsy)
@ -359,7 +359,10 @@ icp start in-coming priority for expression
dc i1'200' ulongconst
dc i1'200' longlongconst
dc i1'200' ulonglongconst
dc i1'200' floatconst
dc i1'200' doubleconst
dc i1'200' extendedconst
dc i1'200' compconst
dc i1'200' stringconst
dc i1'200' _Alignassy
dc i1'16' _Alignofsy
@ -526,7 +529,10 @@ isp start in stack priority for expression
dc i1'0' ulongconst
dc i1'0' longlongconst
dc i1'0' ulonglongconst
dc i1'0' floatconst
dc i1'0' doubleconst
dc i1'0' extendedconst
dc i1'0' compconst
dc i1'0' stringconst
dc i1'0' _Alignassy
dc i1'16' _Alignofsy
@ -899,7 +905,7 @@ wordHash start reserved word hash table
enum ident,0 identifiers
! constants
enum (intconst,uintconst,longconst,ulongconst,longlongconst)
enum (ulonglongconst,extendedconst)
enum (ulonglongconst,floatconst,doubleconst,extendedconst,compconst)
enum stringconst
! reserved words
enum (_Alignassy,_Alignofsy,_Atomicsy,_Boolsy,_Complexsy)