diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile | 3 | ||||
| -rw-r--r-- | src/comp/front/ast.rs | 1 | ||||
| -rw-r--r-- | src/comp/front/lexer.rs | 75 | ||||
| -rw-r--r-- | src/comp/front/parser.rs | 4 | ||||
| -rw-r--r-- | src/comp/front/token.rs | 1 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs | 54 | ||||
| -rw-r--r-- | src/comp/middle/typeck.rs | 4 | ||||
| -rw-r--r-- | src/rt/rust_upcall.cpp | 9 | ||||
| -rw-r--r-- | src/test/run-pass/float2.rs | 23 |
9 files changed, 150 insertions, 24 deletions
diff --git a/src/Makefile b/src/Makefile index 6e014bd2..66c87e9a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -419,7 +419,8 @@ self: $(CFG_RUSTC) # Float doesn't work in boot -FLOAT_XFAILS := test/run-pass/float.rs +FLOAT_XFAILS := test/run-pass/float.rs \ + test/run-pass/float2.rs # Temporarily xfail tests broken by the nominal-tags change. 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); diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index b75af850..b7fb0687 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -763,6 +763,10 @@ fn C_float(str s) -> ValueRef { ret llvm.LLVMConstRealOfString(T_float(), _str.buf(s)); } +fn C_floating(str s, TypeRef t) -> ValueRef { + ret llvm.LLVMConstRealOfString(t, _str.buf(s)); +} + fn C_nil() -> ValueRef { // NB: See comment above in T_void(). ret C_integral(0, T_i1()); @@ -2338,6 +2342,14 @@ fn trans_lit(@crate_ctxt cx, &ast.lit lit, &ast.ann ann) -> ValueRef { case(ast.lit_float(?fs)) { ret C_float(fs); } + case(ast.lit_mach_float(?tm, ?s)) { + auto t = T_float(); + alt(tm) { + case(common.ty_f32) { t = T_f32(); } + case(common.ty_f64) { t = T_f64(); } + } + ret C_floating(s, t); + } case (ast.lit_char(?c)) { ret C_integral(c as int, T_char()); } @@ -2719,7 +2731,7 @@ fn trans_eager_binop(@block_ctxt cx, ast.binop op, @ty.t intype, ValueRef lhs, ValueRef rhs) -> result { auto is_float = false; - alt(intype.struct) { + alt (intype.struct) { case (ty.ty_float) { is_float = true; } @@ -2727,7 +2739,7 @@ fn trans_eager_binop(@block_ctxt cx, ast.binop op, @ty.t intype, is_float = false; } } - + alt (op) { case (ast.add) { if (ty.type_is_sequence(intype)) { @@ -2749,7 +2761,7 @@ fn trans_eager_binop(@block_ctxt cx, ast.binop op, @ty.t intype, } } - case (ast.mul) { + case (ast.mul) { if (is_float) { ret res(cx, cx.build.FMul(lhs, rhs)); } @@ -4582,13 +4594,33 @@ fn trans_log(@block_ctxt cx, @ast.expr e) -> result { auto sub = trans_expr(cx, e); auto e_ty = ty.expr_ty(e); - alt (e_ty.struct) { - case(ty.ty_float) { - auto tmp = sub.bcx.build.Alloca(T_float()); + if (ty.type_is_fp(e_ty)) { + let TypeRef tr; + let bool is32bit = false; + alt (e_ty.struct) { + case (ty.ty_machine(util.common.ty_f32)) { + tr = T_f32(); + is32bit = true; + } + case (ty.ty_machine(util.common.ty_f64)) { + tr = T_f64(); + } + case (_) { + tr = T_float(); + } + } + if (is32bit) { + ret trans_upcall(sub.bcx, + "upcall_log_float", + vec(sub.val)); + } else { + auto tmp = sub.bcx.build.Alloca(tr); sub.bcx.build.Store(sub.val, tmp); - sub = res(sub.bcx, tmp); + auto v = vp2i(sub.bcx, tmp); + ret trans_upcall(sub.bcx, + "upcall_log_double", + vec(v)); } - case(_) { } } alt (e_ty.struct) { @@ -4598,12 +4630,6 @@ fn trans_log(@block_ctxt cx, @ast.expr e) -> result { "upcall_log_str", vec(v)); } - case (ty.ty_float) { - auto v = vp2i(sub.bcx, sub.val); - ret trans_upcall(sub.bcx, - "upcall_log_float", - vec(v)); - } case (_) { ret trans_upcall(sub.bcx, "upcall_log_int", diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index dbeeb8f9..4175af6a 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1497,7 +1497,9 @@ fn check_lit(@ast.lit lit) -> @ty.t { case (ast.lit_str(_)) { sty = ty.ty_str; } case (ast.lit_char(_)) { sty = ty.ty_char; } case (ast.lit_int(_)) { sty = ty.ty_int; } - case (ast.lit_float(_)) { sty = ty.ty_float; } + case (ast.lit_float(_)) { sty = ty.ty_float; } + case (ast.lit_mach_float(?tm, _)) + { sty = ty.ty_machine(tm); } case (ast.lit_uint(_)) { sty = ty.ty_uint; } case (ast.lit_mach_int(?tm, _)) { sty = ty.ty_machine(tm); } case (ast.lit_nil) { sty = ty.ty_nil; } diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index 30306104..19f1ec90 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -40,7 +40,14 @@ void upcall_log_int(rust_task *task, int32_t i) { } extern "C" CDECL -void upcall_log_float(rust_task *task, double *f) { +void upcall_log_float(rust_task *task, float f) { + LOG_UPCALL_ENTRY(task); + task->log(rust_log::UPCALL | rust_log::ULOG, + "rust: %12.12f", f); +} + +extern "C" CDECL +void upcall_log_double(rust_task *task, double *f) { LOG_UPCALL_ENTRY(task); task->log(rust_log::UPCALL | rust_log::ULOG, "rust: %12.12f", *f); diff --git a/src/test/run-pass/float2.rs b/src/test/run-pass/float2.rs new file mode 100644 index 00000000..0c111ba9 --- /dev/null +++ b/src/test/run-pass/float2.rs @@ -0,0 +1,23 @@ +fn main() { + auto a = 1.5e6; + auto b = 1.5E6; + auto c = 1e6; + auto d = 1E6; + auto e = 3.0f32; + auto f = 5.9f64; + auto g = 1.e6f32; + auto h = 1.0e7f64; + auto i = 1.0E7f64; + auto j = 3.1e+9; + auto k = 3.2e-10; + + check(a == b); + check(c < b); + check(c == d); + check(e < g); + check(f < h); + check(g == 1000000.0f32); + check(h == i); + check(j > k); + check(k < a); +}
\ No newline at end of file |