| ... | @@ -293,85 +293,11 @@ static void cancel_token(Tokenize *t) { | ... | @@ -293,85 +293,11 @@ static void cancel_token(Tokenize *t) { |
| 293 | } | 293 | } |
| 294 | | 294 | |
| 295 | static void end_float_token(Tokenize *t) { | 295 | static void end_float_token(Tokenize *t) { |
| 296 | if (t->radix == 10 || t->radix == 16) { | 296 | uint8_t *ptr_buf = (uint8_t*)buf_ptr(t->buf) + t->cur_tok->start_pos; |
| 297 | uint8_t *ptr_buf = (uint8_t*)buf_ptr(t->buf) + t->cur_tok->start_pos; | 297 | size_t buf_len = t->cur_tok->end_pos - t->cur_tok->start_pos; |
| 298 | size_t buf_len = t->cur_tok->end_pos - t->cur_tok->start_pos; | 298 | if (bigfloat_init_buf(&t->cur_tok->data.float_lit.bigfloat, ptr_buf, buf_len)) { |
| 299 | if (bigfloat_init_buf(&t->cur_tok->data.float_lit.bigfloat, ptr_buf, buf_len)) { | | |
| 300 | t->cur_tok->data.float_lit.overflow = true; | | |
| 301 | } | | |
| 302 | return; | | |
| 303 | } | | |
| 304 | | | |
| 305 | BigInt int_max; | | |
| 306 | bigint_init_unsigned(&int_max, INT_MAX); | | |
| 307 | | | |
| 308 | if (bigint_cmp(&t->specified_exponent, &int_max) != CmpLT) { | | |
| 309 | t->cur_tok->data.float_lit.overflow = true; | | |
| 310 | return; | | |
| 311 | } | | |
| 312 | | | |
| 313 | if (!bigint_fits_in_bits(&t->specified_exponent, 128, true)) { | | |
| 314 | t->cur_tok->data.float_lit.overflow = true; | | |
| 315 | return; | | |
| 316 | } | | |
| 317 | | | |
| 318 | int64_t specified_exponent = bigint_as_signed(&t->specified_exponent); | | |
| 319 | if (t->is_exp_negative) { | | |
| 320 | specified_exponent = -specified_exponent; | | |
| 321 | } | | |
| 322 | t->exponent_in_bin_or_dec = (int)(t->exponent_in_bin_or_dec + specified_exponent); | | |
| 323 | | | |
| 324 | if (!bigint_fits_in_bits(&t->significand, 128, false)) { | | |
| 325 | t->cur_tok->data.float_lit.overflow = true; | 299 | t->cur_tok->data.float_lit.overflow = true; |
| 326 | return; | | |
| 327 | } | 300 | } |
| 328 | | | |
| 329 | // A SoftFloat-3e float128 is represented internally as a standard | | |
| 330 | // quad-precision float with 15bit exponent and 112bit fractional. | | |
| 331 | union { uint64_t repr[2]; float128_t actual; } f_bits; | | |
| 332 | | | |
| 333 | if (bigint_cmp_zero(&t->significand) == CmpEQ) { | | |
| 334 | f_bits.repr[0] = 0; | | |
| 335 | f_bits.repr[1] = 0; | | |
| 336 | } else { | | |
| 337 | int significand_magnitude_in_bin = 127 - bigint_clz(&t->significand, 128); | | |
| 338 | t->exponent_in_bin_or_dec += significand_magnitude_in_bin; | | |
| 339 | if (!(-16382 <= t->exponent_in_bin_or_dec && t->exponent_in_bin_or_dec <= 16383)) { | | |
| 340 | t->cur_tok->data.float_lit.overflow = true; | | |
| 341 | return; | | |
| 342 | } | | |
| 343 | | | |
| 344 | // Shift bits of significand so they are left-justified at the 112-bit | | |
| 345 | // mark. We truncate excess bits and lose precision. No rounding. | | |
| 346 | // | | |
| 347 | // -16 <= shift <= 112 | | |
| 348 | // | | |
| 349 | // NOTE: The loss of precision could be considered a limitation of using | | |
| 350 | // 128-bit floats. In stage2 we should use an arbitrary precision | | |
| 351 | // float/rational type to represent these and avoid this. | | |
| 352 | const int shift = 112 - significand_magnitude_in_bin; | | |
| 353 | bigint_write_twos_complement(&t->significand, (uint8_t*) f_bits.repr, 128, false); | | |
| 354 | | | |
| 355 | if (shift >= 64) { | | |
| 356 | f_bits.repr[1] = f_bits.repr[0] << (shift - 64); | | |
| 357 | f_bits.repr[0] = 0; | | |
| 358 | } else if (shift > 0) { | | |
| 359 | f_bits.repr[1] = (f_bits.repr[1] << shift) | (f_bits.repr[0] >> (64 - shift)); | | |
| 360 | f_bits.repr[0] = f_bits.repr[0] << shift; | | |
| 361 | } else if (shift < 0) { | | |
| 362 | int positive_shift = -shift; | | |
| 363 | assert(positive_shift <= 16); | | |
| 364 | f_bits.repr[0] = (f_bits.repr[0] >> positive_shift) | (f_bits.repr[1] << (64 - positive_shift)); | | |
| 365 | f_bits.repr[1] = f_bits.repr[1] >> positive_shift; | | |
| 366 | } | | |
| 367 | | | |
| 368 | // Lexer separates negative sign from value so this is always non-negative. | | |
| 369 | const uint64_t exp_mask = 0xffffull << 48; | | |
| 370 | f_bits.repr[1] &= ~exp_mask; | | |
| 371 | f_bits.repr[1] |= (uint64_t)(t->exponent_in_bin_or_dec + 16383) << 48; | | |
| 372 | } | | |
| 373 | | | |
| 374 | bigfloat_init_128(&t->cur_tok->data.float_lit.bigfloat, f_bits.actual); | | |
| 375 | } | 301 | } |
| 376 | | 302 | |
| 377 | static void end_token(Tokenize *t) { | 303 | static void end_token(Tokenize *t) { |
| ... | @@ -1265,10 +1191,16 @@ void tokenize(Buf *buf, Tokenization *out) { | ... | @@ -1265,10 +1191,16 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 1265 | case TokenizeStateNumber: | 1191 | case TokenizeStateNumber: |
| 1266 | { | 1192 | { |
| 1267 | if (c == '.') { | 1193 | if (c == '.') { |
| | 1194 | if (t.radix != 16 && t.radix != 10) { |
| | 1195 | invalid_char_error(&t, c); |
| | 1196 | } |
| 1268 | t.state = TokenizeStateNumberDot; | 1197 | t.state = TokenizeStateNumberDot; |
| 1269 | break; | 1198 | break; |
| 1270 | } | 1199 | } |
| 1271 | if (is_exponent_signifier(c, t.radix)) { | 1200 | if (is_exponent_signifier(c, t.radix)) { |
| | 1201 | if (t.radix != 16 && t.radix != 10) { |
| | 1202 | invalid_char_error(&t, c); |
| | 1203 | } |
| 1272 | t.state = TokenizeStateFloatExponentUnsigned; | 1204 | t.state = TokenizeStateFloatExponentUnsigned; |
| 1273 | assert(t.cur_tok->id == TokenIdIntLiteral); | 1205 | assert(t.cur_tok->id == TokenIdIntLiteral); |
| 1274 | bigint_init_bigint(&t.significand, &t.cur_tok->data.int_lit.bigint); | 1206 | bigint_init_bigint(&t.significand, &t.cur_tok->data.int_lit.bigint); |