Skip to content

Commit

Permalink
Parse FP literals without coercing to int. This allows parsing 64-bit
Browse files Browse the repository at this point in the history
floats. However, if someone writes a literal that can't be represented
precisely in 64 bits, the front-end will accept it while the back-end
will (presumably) complain.
  • Loading branch information
catamorphism committed Mar 25, 2011
1 parent e2d6475 commit a47cd50
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 39 deletions.
6 changes: 3 additions & 3 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,8 @@ docsnap: doc/rust.pdf

FLOAT_XFAILS := $(S)src/test/run-pass/float.rs \
$(S)src/test/run-pass/float2.rs \
$(S)src/test/run-pass/float-signature.rs
$(S)src/test/run-pass/float-signature.rs \
$(S)src/test/run-pass/floatlits.rs

# Temporarily xfail tests broken by the nominal-tags change.

Expand Down Expand Up @@ -641,8 +642,7 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \
writing-through-read-alias.rs) \
$(S)src/test/bench/shootout/nbody.rs

TEST_XFAILS_STAGE0 := $(FLOAT_XFAILS) \
$(addprefix $(S)src/test/run-pass/, \
TEST_XFAILS_STAGE0 := $(addprefix $(S)src/test/run-pass/, \
acyclic-unwind.rs \
alt-pattern-drop.rs \
alt-type-simple.rs \
Expand Down
95 changes: 59 additions & 36 deletions src/comp/front/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,47 +318,65 @@ impure fn consume_block_comment(reader rdr) {
be consume_any_whitespace(rdr);
}

impure fn scan_dec_digits(reader rdr) -> int {

auto c = rdr.curr();
fn digits_to_string(str s) -> int {

let int accum_int = 0;
let int i = 0;

while (is_dec_digit(c) || c == '_') {
if (c != '_') {
accum_int *= 10;
accum_int += dec_digit_val(c);
}
rdr.bump();
c = rdr.curr();
for (u8 c in s) {
accum_int *= 10;
accum_int += dec_digit_val(c as char);
}

ret accum_int;
}

impure fn scan_exponent(reader rdr) -> option.t[int] {
impure fn scan_exponent(reader rdr) -> option.t[str] {
auto c = rdr.curr();
auto sign = 1;
auto res = "";

if (c == 'e' || c == 'E') {
res += _str.from_bytes(vec(c as u8));
rdr.bump();
c = rdr.curr();
if (c == '-') {
sign = -1;
rdr.bump();
} else if (c == '+') {
if (c == '-' || c == '+') {
res += _str.from_bytes(vec(c as u8));
rdr.bump();
}
auto exponent = scan_dec_digits(rdr);
ret(some(sign * exponent));
if (_str.byte_len(exponent) > 0u) {
ret(some(res + exponent));
}
else {
log ("scan_exponent: bad fp literal");
fail;
}
}
else {
ret none[int];
ret none[str];
}
}

impure fn scan_dec_digits(reader rdr) -> str {

auto c = rdr.curr();
let str res = "";

while (is_dec_digit (c) || c == '_') {
if (c != '_') {
res += _str.from_bytes(vec(c as u8));
}
rdr.bump();
c = rdr.curr();
}

ret res;
}

impure fn scan_number(mutable char c, reader rdr) -> token.token {
auto accum_int = 0;
let str dec_str = "";
let bool is_dec_integer = false;
auto n = rdr.next();

if (c == '0' && n == 'x') {
Expand Down Expand Up @@ -386,7 +404,12 @@ impure fn scan_number(mutable char c, reader rdr) -> token.token {
c = rdr.curr();
}
} else {
accum_int = scan_dec_digits(rdr);
dec_str = scan_dec_digits(rdr);
is_dec_integer = true;
}

if (is_dec_integer) {
accum_int = digits_to_string(dec_str);
}

c = rdr.curr();
Expand Down Expand Up @@ -443,20 +466,19 @@ impure fn scan_number(mutable char c, reader rdr) -> token.token {
}
}
c = rdr.curr();

if (c == '.') {
// Parse a floating-point number.
rdr.bump();
auto accum_int1 = scan_dec_digits(rdr);
auto base_str = _int.to_str(accum_int, 10u) + "."
+ _int.to_str(accum_int1, 10u);
auto dec_part = scan_dec_digits(rdr);
auto float_str = dec_str + "." + dec_part;
c = rdr.curr();
auto exponent_str = "";
let option.t[int] maybe_exponent = scan_exponent(rdr);
alt(maybe_exponent) {
case(some[int](?i)) {
exponent_str = "e" + _int.to_str(i, 10u);
auto exponent_str = scan_exponent(rdr);
alt (exponent_str) {
case (some[str](?s)) {
float_str += s;
}
case(none[int]) {
case (none[str]) {
}
}

Expand All @@ -468,27 +490,28 @@ impure fn scan_number(mutable char c, reader rdr) -> token.token {
if (c == '3' && n == '2') {
rdr.bump(); rdr.bump();
ret token.LIT_MACH_FLOAT(util.common.ty_f32,
base_str + exponent_str);
float_str);
}
else if (c == '6' && n == '4') {
rdr.bump(); rdr.bump();
ret token.LIT_MACH_FLOAT(util.common.ty_f64,
base_str + exponent_str);
float_str);
/* FIXME: if this is out of range for either a 32-bit or
64-bit float, it won't be noticed till the back-end */
}
}
else {
ret token.LIT_FLOAT(base_str + exponent_str);
ret token.LIT_FLOAT(float_str);
}
}

auto maybe_exponent = scan_exponent(rdr);
alt(maybe_exponent) {
case(some[int](?i)) {
ret token.LIT_FLOAT(_int.to_str(accum_int, 10u)
+ "e" + _int.to_str(i, 10u));
case(some[str](?s)) {
ret token.LIT_FLOAT(dec_str + s);
}
case(none[int]) {
ret token.LIT_INT(accum_int);
case(none[str]) {
ret token.LIT_INT(accum_int);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/rt/rustrt.def.in
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ upcall_grow_task
upcall_join
upcall_kill
upcall_log_double
upcall_log_float
upcall_log_int
upcall_log_str
upcall_malloc
Expand Down
8 changes: 8 additions & 0 deletions src/test/run-pass/floatlits.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fn main() {
auto f = 4.999999999999;
check (f > 4.90);
check (f < 5.0);
auto g = 4.90000000001e-10;
check(g > 5e-11);
check(g < 5e-9);
}

0 comments on commit a47cd50

Please sign in to comment.