next up previous
Next: Floating-Point Literals Up: Literals Previous: Literals

Integer 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.

Integer Literal[16]:

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:

IntegerLiteral[17]:
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 up previous
Next: Floating-Point Literals Up: Literals Previous: Literals
2008-09-11