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} ident, {identifiers}
{constants} {constants}
intconst,uintconst,longconst,ulongconst,longlongconst, intconst,uintconst,longconst,ulongconst,longlongconst,
ulonglongconst,extendedconst, ulonglongconst,floatconst,doubleconst,extendedconst,compconst,
stringconst, stringconst,
{reserved words} {reserved words}
_Alignassy,_Alignofsy,_Atomicsy,_Boolsy,_Complexsy, _Alignassy,_Alignofsy,_Atomicsy,_Boolsy,_Complexsy,

View File

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

View File

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

View File

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

View File

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