I6 Template Layer

Inform 7 6M62ContentsIntroductionFunction IndexRules Index

Number.i6t

Number contents

Understanding.

In our target virtual machines, numbers are stored in twos-complement form, so that a 16-bit VM can hold the range of integers -215 = -32768 to 215-1 = +32767, while a 32-bit VM can hold -231 = -2147483648 to 231-1 = +2147483647: the token below accepts exactly those ranges.

14[ DECIMAL_TOKEN wnc wna r n wa wl sign base digit digit_count original_wn group_wn; 15    wnc = wn; original_wn = wn; group_wn = wn; 16{-call:PL::Parsing::Tokens::Values::number} 17    wn = wnc; 18    r = ParseTokenStopped(ELEMENTARY_TT, NUMBER_TOKEN); 19    if ((r == GPR_NUMBER) && (parsed_number ~= 10000)) return r; 20    wn = wnc; 21    wa = WordAddress(wn); 22    wl = WordLength(wn); 23    sign = 1; base = 10; digit_count = 0; 24    if (wa->0 ~= '-' or '$' or '0' or '1' or '2' or '3' or '4' 25        or '5' or '6' or '7' or '8' or '9') 26        return GPR_FAIL; 27    if (wa->0 == '-') { sign = -1; wl--; wa++; } 28    if (wl == 0) return GPR_FAIL; 29    n = 0; 30    while (wl > 0) { 31        if (wa->0 >= 'a') digit = wa->0 - 'a' + 10; 32        else digit = wa->0 - '0'; 33        digit_count++; 34        switch (base) { 35            2: if (digit_count == 17) return GPR_FAIL; 36            10: 37                #Iftrue (WORDSIZE == 2); 38                if (digit_count == 6) return GPR_FAIL; 39                if (digit_count == 5) { 40                    if (n > 3276) return GPR_FAIL; 41                    if (n == 3276) { 42                        if (sign == 1 && digit > 7) return GPR_FAIL; 43                        if (sign == -1 && digit > 8) return GPR_FAIL; 44                    } 45                } 46                #Ifnot; ! i.e., if (WORDSIZE == 4) 47                if (digit_count == 11) return GPR_FAIL; 48                if (digit_count == 10) { 49                    if (n > 214748364) return GPR_FAIL; 50                    if (n == 214748364) { 51                        if (sign == 1 && digit > 7) return GPR_FAIL; 52                        if (sign == -1 && digit > 8) return GPR_FAIL; 53                    } 54                } 55                #Endif; 56            16: if (digit_count == 5) return GPR_FAIL; 57        } 58        if (digit >= 0 && digit < base) n = base*n + digit; 59        else return GPR_FAIL; 60        wl--; wa++; 61    } 62    parsed_number = n*sign; wn++; 63    return GPR_NUMBER; 64];

Truth states.

And although truth states are not strictly speaking numbers, this seems as good a point as any to parse them:

71[ TRUTH_STATE_TOKEN original_wn wd; 72    original_wn = wn; 73{-call:PL::Parsing::Tokens::Values::truth_state} 74    wn = original_wn; 75    wd = NextWordStopped(); 76    if (wd == 'true') { parsed_number = 1; return GPR_NUMBER; } 77    if (wd == 'false') { parsed_number = 0; return GPR_NUMBER; } 78    wn = original_wn; 79    return GPR_FAIL; 80];

Absolute value.

It's convenient to have this around somewhere:

86[ NUMBER_TY_Abs x; if (x<0) return -x; return x; ];