Next: Floating-Point Literals
Up: Literals
Previous: Literals
Integer literals are decomposed by type in order to preserve type
information gleaned during lexical analysis.
If this information were not preserved, later components of the compiler
would be forced to re-scan the characters of the literal to obtain it.
IntLiteral: $0|[1-9][0-9]* [mkint10]
$0[xX][0-9a-fA-F]+ [mkint16]
$0[0-7]+ [mkint8]
LongLiteral: $(0|[1-9][0-9]*)[lL] [mklng10]
$0[xX][0-9a-fA-F]+[lL] [mklng16]
$0[0-7]+[lL] [mklng8]
This macro is invoked in definition 12.
The grammar symbol IntegerLiteral is expanded to retain the type
information:
IntLiteral / LongLiteral
This macro is invoked in definition 39.
The token processors normalize the integer to decimal form to guarantee that
integer literals with the same value have the same internal representation.
Thus if i is the internal representation of an integer literal,
StringTable(i) is always a null-terminated sequence of decimal digits from
the set [0-9].
Normalize a literal value[18]
:
Token processor[1](`mkint10')
{ NormInt(c, l, t, s, 10); *t = IntLiteral; }
Token processor[1](`mkint16')
{ NormInt(c + 2, l - 2, t, s, 16); *t = IntLiteral; }
Token processor[1](`mkint8')
{ NormInt(c, l, t, s, 8); *t = IntLiteral; }
Token processor[1](`mklng10')
{ NormInt(c, l - 1, t, s, 10); *t = LongLiteral; }
Token processor[1](`mklng16')
{ NormInt(c + 2, l - 3, t, s, 16); *t = LongLiteral; }
Token processor[1](`mklng8')
{ NormInt(c, l - 1, t, s, 8); *t = LongLiteral; }
This macro is defined in definitions 18, 25, and 31.
This macro is invoked in definition 37.
The actual normalization is performed by invoking the string arithmetic
package from the Eli library:
NormInt(char *c, int l, int *t, int *s, int r)[19]
:
/* On entry-
* c points to the first character of the scanned string
* l=length of the scanned string
* *t=initial classification
* r=radix of the number to be normalized
* On exit-
* *t=final classification
* *s=internal representation
***/
{ char save, *num, *temp, complement[ARITH_SIZE*2];
int error;
save = c[l]; c[l] = '\0';
/* Maximum values taken from section 3.10.1 of the language specification */
if (*t == IntLiteral) {
if (r == 8) {
temp = strsub(c, "40000000000", 8);
error = (!temp || temp[0] != '-');
if (!error) {
strcpy(complement, temp);
num = strsub("17777777777", c, 8);
if (num[0] == '-')
num = strnorm(complement, 8, 10, "");
else
num = strnorm(c, 8, 10, "");
}
} else if (r == 10) {
temp = strsub(c, "2147483649", 10);
error = (!temp || temp[0] != '-');
if (!error)
num = strnorm(c, 10, 10, "");
} else { /* r == 16 */
temp = strsub(c, "100000000", 16);
error = (!temp || temp[0] != '-');
if (!error) {
strcpy(complement, temp);
num = strsub("7fffffff", c, 16);
if (num[0] == '-')
num = strnorm(complement, 16, 10, "");
else
num = strnorm(c, 16, 10, "");
}
}
} else { /* *t == LongLiteral */
if (r == 8) {
temp = strsub(c, "2000000000000000000000", 8);
error = (!temp || temp[0] != '-');
if (!error) {
strcpy(complement, temp);
num = strsub("777777777777777777777", c, 8);
if (num[0] == '-')
num = strnorm(complement, 8, 10, "");
else
num = strnorm(c, 8, 10, "");
}
} else if (r == 10) {
temp = strsub(c, "9223372036854775809", 10);
error = (!temp || temp[0] != '-');
if (!error)
num = strnorm(c, 10, 10, "");
} else { /* r == 16 */
temp = strsub(c, "10000000000000000", 16);
error = (!temp || temp[0] != '-');
if (!error) {
strcpy(complement, temp);
num = strsub("7fffffffffffffff", c, 16);
if (num[0] == '-')
num = strnorm(complement, 16, 10, "");
else
num = strnorm(c, 16, 10, "");
}
}
}
if (error) {
message(ERROR, "Integer overflow", 0, &curpos);
*s = 0; return;
}
c[l] = save;
mkidn(num, strlen(num), t, s);
}
This macro is invoked in definition 37.
If an overflow is detected, the internal representation is set to 0.
StringTable[0] is the internal representation of a null string, and is
therefore different from the representation of any valid integer.
Next: Floating-Point Literals
Up: Literals
Previous: Literals
2008-09-11