aboutsummaryrefslogtreecommitdiff
path: root/src/tokenizer.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2019-03-23 14:04:52 -0400
committerAndrew Kelley <andrew@ziglang.org>2019-03-23 14:04:52 -0400
commit3e9697bb35267973554155cedc2e593bd4519dd8 (patch)
tree86868b584d74643e091c2858bfd3f4425264ae26 /src/tokenizer.cpp
parent14d416f83b4dabeb714d7001f6efa4fcbac180d5 (diff)
downloadzig-3e9697bb35267973554155cedc2e593bd4519dd8.tar.gz
zig-3e9697bb35267973554155cedc2e593bd4519dd8.zip
remove octal and hex floats from the language
closes #2093 This is technically a breaking change but I would be surprised if anyone was actually using this feature.
Diffstat (limited to 'src/tokenizer.cpp')
-rw-r--r--src/tokenizer.cpp86
1 files changed, 9 insertions, 77 deletions
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index b050944884..dc9d61aa22 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -293,85 +293,11 @@ static void cancel_token(Tokenize *t) {
}
static void end_float_token(Tokenize *t) {
- if (t->radix == 10 || t->radix == 16) {
- uint8_t *ptr_buf = (uint8_t*)buf_ptr(t->buf) + t->cur_tok->start_pos;
- size_t buf_len = t->cur_tok->end_pos - t->cur_tok->start_pos;
- if (bigfloat_init_buf(&t->cur_tok->data.float_lit.bigfloat, ptr_buf, buf_len)) {
- t->cur_tok->data.float_lit.overflow = true;
- }
- return;
- }
-
- BigInt int_max;
- bigint_init_unsigned(&int_max, INT_MAX);
-
- if (bigint_cmp(&t->specified_exponent, &int_max) != CmpLT) {
- t->cur_tok->data.float_lit.overflow = true;
- return;
- }
-
- if (!bigint_fits_in_bits(&t->specified_exponent, 128, true)) {
- t->cur_tok->data.float_lit.overflow = true;
- return;
- }
-
- int64_t specified_exponent = bigint_as_signed(&t->specified_exponent);
- if (t->is_exp_negative) {
- specified_exponent = -specified_exponent;
- }
- t->exponent_in_bin_or_dec = (int)(t->exponent_in_bin_or_dec + specified_exponent);
-
- if (!bigint_fits_in_bits(&t->significand, 128, false)) {
+ uint8_t *ptr_buf = (uint8_t*)buf_ptr(t->buf) + t->cur_tok->start_pos;
+ size_t buf_len = t->cur_tok->end_pos - t->cur_tok->start_pos;
+ if (bigfloat_init_buf(&t->cur_tok->data.float_lit.bigfloat, ptr_buf, buf_len)) {
t->cur_tok->data.float_lit.overflow = true;
- return;
}
-
- // A SoftFloat-3e float128 is represented internally as a standard
- // quad-precision float with 15bit exponent and 112bit fractional.
- union { uint64_t repr[2]; float128_t actual; } f_bits;
-
- if (bigint_cmp_zero(&t->significand) == CmpEQ) {
- f_bits.repr[0] = 0;
- f_bits.repr[1] = 0;
- } else {
- int significand_magnitude_in_bin = 127 - bigint_clz(&t->significand, 128);
- t->exponent_in_bin_or_dec += significand_magnitude_in_bin;
- if (!(-16382 <= t->exponent_in_bin_or_dec && t->exponent_in_bin_or_dec <= 16383)) {
- t->cur_tok->data.float_lit.overflow = true;
- return;
- }
-
- // Shift bits of significand so they are left-justified at the 112-bit
- // mark. We truncate excess bits and lose precision. No rounding.
- //
- // -16 <= shift <= 112
- //
- // NOTE: The loss of precision could be considered a limitation of using
- // 128-bit floats. In stage2 we should use an arbitrary precision
- // float/rational type to represent these and avoid this.
- const int shift = 112 - significand_magnitude_in_bin;
- bigint_write_twos_complement(&t->significand, (uint8_t*) f_bits.repr, 128, false);
-
- if (shift >= 64) {
- f_bits.repr[1] = f_bits.repr[0] << (shift - 64);
- f_bits.repr[0] = 0;
- } else if (shift > 0) {
- f_bits.repr[1] = (f_bits.repr[1] << shift) | (f_bits.repr[0] >> (64 - shift));
- f_bits.repr[0] = f_bits.repr[0] << shift;
- } else if (shift < 0) {
- int positive_shift = -shift;
- assert(positive_shift <= 16);
- f_bits.repr[0] = (f_bits.repr[0] >> positive_shift) | (f_bits.repr[1] << (64 - positive_shift));
- f_bits.repr[1] = f_bits.repr[1] >> positive_shift;
- }
-
- // Lexer separates negative sign from value so this is always non-negative.
- const uint64_t exp_mask = 0xffffull << 48;
- f_bits.repr[1] &= ~exp_mask;
- f_bits.repr[1] |= (uint64_t)(t->exponent_in_bin_or_dec + 16383) << 48;
- }
-
- bigfloat_init_128(&t->cur_tok->data.float_lit.bigfloat, f_bits.actual);
}
static void end_token(Tokenize *t) {
@@ -1265,10 +1191,16 @@ void tokenize(Buf *buf, Tokenization *out) {
case TokenizeStateNumber:
{
if (c == '.') {
+ if (t.radix != 16 && t.radix != 10) {
+ invalid_char_error(&t, c);
+ }
t.state = TokenizeStateNumberDot;
break;
}
if (is_exponent_signifier(c, t.radix)) {
+ if (t.radix != 16 && t.radix != 10) {
+ invalid_char_error(&t, c);
+ }
t.state = TokenizeStateFloatExponentUnsigned;
assert(t.cur_tok->id == TokenIdIntLiteral);
bigint_init_bigint(&t.significand, &t.cur_tok->data.int_lit.bigint);