From 23e23bd762a4b5a14ff2abcbabfd2349621a3dbe Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 22 Mar 2011 17:25:40 -0700 Subject: Further support for floating-point. Literals with exponents work and literals with the 'f32' or 'f64' suffixes work as well. In addition, logging things with the f32 or f64 type works. (float is still assumed to be a synonym for f64). --- src/comp/front/ast.rs | 1 + src/comp/front/lexer.rs | 75 +++++++++++++++++++++++++++++++++++++++++++----- src/comp/front/parser.rs | 4 +++ src/comp/front/token.rs | 1 + 4 files changed, 74 insertions(+), 7 deletions(-) (limited to 'src/comp/front') diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index cdeea241..d48792d1 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -256,6 +256,7 @@ tag lit_ { lit_uint(uint); lit_mach_int(ty_mach, int); lit_float(str); + lit_mach_float(ty_mach, str); lit_nil; lit_bool(bool); } diff --git a/src/comp/front/lexer.rs b/src/comp/front/lexer.rs index d4948503..aa7f2ce1 100644 --- a/src/comp/front/lexer.rs +++ b/src/comp/front/lexer.rs @@ -3,6 +3,9 @@ import std._str; import std._int; import std.map; import std.map.hashmap; +import std.option; +import std.option.some; +import std.option.none; import util.common; import util.common.new_str_hash; @@ -333,6 +336,27 @@ impure fn scan_dec_digits(reader rdr) -> int { ret accum_int; } +impure fn scan_exponent(reader rdr) -> option.t[int] { + auto c = rdr.curr(); + auto sign = 1; + + if (c == 'e' || c == 'E') { + rdr.bump(); + c = rdr.curr(); + if (c == '-') { + sign = -1; + rdr.bump(); + } else if (c == '+') { + rdr.bump(); + } + auto exponent = scan_dec_digits(rdr); + ret(some(sign * exponent)); + } + else { + ret none[int]; + } +} + impure fn scan_number(mutable char c, reader rdr) -> token.token { auto accum_int = 0; auto n = rdr.next(); @@ -418,17 +442,54 @@ impure fn scan_number(mutable char c, reader rdr) -> token.token { ret token.LIT_UINT(accum_int as uint); } } - n = rdr.curr(); - if(n == '.') { + c = rdr.curr(); + if (c == '.') { // Parse a floating-point number. rdr.bump(); auto accum_int1 = scan_dec_digits(rdr); - ret token.LIT_FLOAT(_int.to_str(accum_int, 10u) + "." - + _int.to_str(accum_int1, 10u)); - // FIXME: Parse exponent. + auto base_str = _int.to_str(accum_int, 10u) + "." + + _int.to_str(accum_int1, 10u); + 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); + } + case(none[int]) { + } + } + + c = rdr.curr(); + if (c == 'f') { + rdr.bump(); + c = rdr.curr(); + n = rdr.next(); + if (c == '3' && n == '2') { + rdr.bump(); rdr.bump(); + ret token.LIT_MACH_FLOAT(util.common.ty_f32, + base_str + exponent_str); + } + else if (c == '6' && n == '4') { + rdr.bump(); rdr.bump(); + ret token.LIT_MACH_FLOAT(util.common.ty_f64, + base_str + exponent_str); + } + } + else { + ret token.LIT_FLOAT(base_str + exponent_str); + } } - else { - ret token.LIT_INT(accum_int); + + 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(none[int]) { + ret token.LIT_INT(accum_int); + } } } diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index f1f8a918..9e13e706 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -545,6 +545,10 @@ impure fn parse_lit(parser p) -> ast.lit { p.bump(); lit = ast.lit_mach_int(tm, i); } + case (token.LIT_MACH_FLOAT(?tm, ?s)) { + p.bump(); + lit = ast.lit_mach_float(tm, s); + } case (token.LIT_CHAR(?c)) { p.bump(); lit = ast.lit_char(c); diff --git a/src/comp/front/token.rs b/src/comp/front/token.rs index a1fb1cd0..46fd0735 100644 --- a/src/comp/front/token.rs +++ b/src/comp/front/token.rs @@ -127,6 +127,7 @@ tag token { LIT_UINT(uint); LIT_MACH_INT(ty_mach, int); LIT_FLOAT(str); + LIT_MACH_FLOAT(ty_mach, str); LIT_STR(str); LIT_CHAR(char); LIT_BOOL(bool); -- cgit v1.2.3