Skip to content

Commit 23e23bd

Browse files
catamorphismgraydon
authored andcommitted
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).
1 parent d56971d commit 23e23bd

File tree

10 files changed

+152
-25
lines changed

10 files changed

+152
-25
lines changed

Makefile.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,8 @@ rustllvm/%.o: rustllvm/%.cpp $(MKFILES)
486486

487487
# Float doesn't work in boot
488488

489-
FLOAT_XFAILS := test/run-pass/float.rs
489+
FLOAT_XFAILS := test/run-pass/float.rs \
490+
test/run-pass/float2.rs
490491

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

src/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,8 @@ self: $(CFG_RUSTC)
419419

420420
# Float doesn't work in boot
421421

422-
FLOAT_XFAILS := test/run-pass/float.rs
422+
FLOAT_XFAILS := test/run-pass/float.rs \
423+
test/run-pass/float2.rs
423424

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

src/comp/front/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ tag lit_ {
256256
lit_uint(uint);
257257
lit_mach_int(ty_mach, int);
258258
lit_float(str);
259+
lit_mach_float(ty_mach, str);
259260
lit_nil;
260261
lit_bool(bool);
261262
}

src/comp/front/lexer.rs

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import std._str;
33
import std._int;
44
import std.map;
55
import std.map.hashmap;
6+
import std.option;
7+
import std.option.some;
8+
import std.option.none;
69
import util.common;
710
import util.common.new_str_hash;
811

@@ -333,6 +336,27 @@ impure fn scan_dec_digits(reader rdr) -> int {
333336
ret accum_int;
334337
}
335338

339+
impure fn scan_exponent(reader rdr) -> option.t[int] {
340+
auto c = rdr.curr();
341+
auto sign = 1;
342+
343+
if (c == 'e' || c == 'E') {
344+
rdr.bump();
345+
c = rdr.curr();
346+
if (c == '-') {
347+
sign = -1;
348+
rdr.bump();
349+
} else if (c == '+') {
350+
rdr.bump();
351+
}
352+
auto exponent = scan_dec_digits(rdr);
353+
ret(some(sign * exponent));
354+
}
355+
else {
356+
ret none[int];
357+
}
358+
}
359+
336360
impure fn scan_number(mutable char c, reader rdr) -> token.token {
337361
auto accum_int = 0;
338362
auto n = rdr.next();
@@ -418,17 +442,54 @@ impure fn scan_number(mutable char c, reader rdr) -> token.token {
418442
ret token.LIT_UINT(accum_int as uint);
419443
}
420444
}
421-
n = rdr.curr();
422-
if(n == '.') {
445+
c = rdr.curr();
446+
if (c == '.') {
423447
// Parse a floating-point number.
424448
rdr.bump();
425449
auto accum_int1 = scan_dec_digits(rdr);
426-
ret token.LIT_FLOAT(_int.to_str(accum_int, 10u) + "."
427-
+ _int.to_str(accum_int1, 10u));
428-
// FIXME: Parse exponent.
450+
auto base_str = _int.to_str(accum_int, 10u) + "."
451+
+ _int.to_str(accum_int1, 10u);
452+
c = rdr.curr();
453+
auto exponent_str = "";
454+
let option.t[int] maybe_exponent = scan_exponent(rdr);
455+
alt(maybe_exponent) {
456+
case(some[int](?i)) {
457+
exponent_str = "e" + _int.to_str(i, 10u);
458+
}
459+
case(none[int]) {
460+
}
461+
}
462+
463+
c = rdr.curr();
464+
if (c == 'f') {
465+
rdr.bump();
466+
c = rdr.curr();
467+
n = rdr.next();
468+
if (c == '3' && n == '2') {
469+
rdr.bump(); rdr.bump();
470+
ret token.LIT_MACH_FLOAT(util.common.ty_f32,
471+
base_str + exponent_str);
472+
}
473+
else if (c == '6' && n == '4') {
474+
rdr.bump(); rdr.bump();
475+
ret token.LIT_MACH_FLOAT(util.common.ty_f64,
476+
base_str + exponent_str);
477+
}
478+
}
479+
else {
480+
ret token.LIT_FLOAT(base_str + exponent_str);
481+
}
429482
}
430-
else {
431-
ret token.LIT_INT(accum_int);
483+
484+
auto maybe_exponent = scan_exponent(rdr);
485+
alt(maybe_exponent) {
486+
case(some[int](?i)) {
487+
ret token.LIT_FLOAT(_int.to_str(accum_int, 10u)
488+
+ "e" + _int.to_str(i, 10u));
489+
}
490+
case(none[int]) {
491+
ret token.LIT_INT(accum_int);
492+
}
432493
}
433494
}
434495

src/comp/front/parser.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,10 @@ impure fn parse_lit(parser p) -> ast.lit {
545545
p.bump();
546546
lit = ast.lit_mach_int(tm, i);
547547
}
548+
case (token.LIT_MACH_FLOAT(?tm, ?s)) {
549+
p.bump();
550+
lit = ast.lit_mach_float(tm, s);
551+
}
548552
case (token.LIT_CHAR(?c)) {
549553
p.bump();
550554
lit = ast.lit_char(c);

src/comp/front/token.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ tag token {
127127
LIT_UINT(uint);
128128
LIT_MACH_INT(ty_mach, int);
129129
LIT_FLOAT(str);
130+
LIT_MACH_FLOAT(ty_mach, str);
130131
LIT_STR(str);
131132
LIT_CHAR(char);
132133
LIT_BOOL(bool);

src/comp/middle/trans.rs

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,10 @@ fn C_float(str s) -> ValueRef {
763763
ret llvm.LLVMConstRealOfString(T_float(), _str.buf(s));
764764
}
765765

766+
fn C_floating(str s, TypeRef t) -> ValueRef {
767+
ret llvm.LLVMConstRealOfString(t, _str.buf(s));
768+
}
769+
766770
fn C_nil() -> ValueRef {
767771
// NB: See comment above in T_void().
768772
ret C_integral(0, T_i1());
@@ -2338,6 +2342,14 @@ fn trans_lit(@crate_ctxt cx, &ast.lit lit, &ast.ann ann) -> ValueRef {
23382342
case(ast.lit_float(?fs)) {
23392343
ret C_float(fs);
23402344
}
2345+
case(ast.lit_mach_float(?tm, ?s)) {
2346+
auto t = T_float();
2347+
alt(tm) {
2348+
case(common.ty_f32) { t = T_f32(); }
2349+
case(common.ty_f64) { t = T_f64(); }
2350+
}
2351+
ret C_floating(s, t);
2352+
}
23412353
case (ast.lit_char(?c)) {
23422354
ret C_integral(c as int, T_char());
23432355
}
@@ -2719,15 +2731,15 @@ fn trans_eager_binop(@block_ctxt cx, ast.binop op, @ty.t intype,
27192731
ValueRef lhs, ValueRef rhs) -> result {
27202732

27212733
auto is_float = false;
2722-
alt(intype.struct) {
2734+
alt (intype.struct) {
27232735
case (ty.ty_float) {
27242736
is_float = true;
27252737
}
27262738
case (_) {
27272739
is_float = false;
27282740
}
27292741
}
2730-
2742+
27312743
alt (op) {
27322744
case (ast.add) {
27332745
if (ty.type_is_sequence(intype)) {
@@ -2749,7 +2761,7 @@ fn trans_eager_binop(@block_ctxt cx, ast.binop op, @ty.t intype,
27492761
}
27502762
}
27512763

2752-
case (ast.mul) {
2764+
case (ast.mul) {
27532765
if (is_float) {
27542766
ret res(cx, cx.build.FMul(lhs, rhs));
27552767
}
@@ -4582,13 +4594,33 @@ fn trans_log(@block_ctxt cx, @ast.expr e) -> result {
45824594

45834595
auto sub = trans_expr(cx, e);
45844596
auto e_ty = ty.expr_ty(e);
4585-
alt (e_ty.struct) {
4586-
case(ty.ty_float) {
4587-
auto tmp = sub.bcx.build.Alloca(T_float());
4597+
if (ty.type_is_fp(e_ty)) {
4598+
let TypeRef tr;
4599+
let bool is32bit = false;
4600+
alt (e_ty.struct) {
4601+
case (ty.ty_machine(util.common.ty_f32)) {
4602+
tr = T_f32();
4603+
is32bit = true;
4604+
}
4605+
case (ty.ty_machine(util.common.ty_f64)) {
4606+
tr = T_f64();
4607+
}
4608+
case (_) {
4609+
tr = T_float();
4610+
}
4611+
}
4612+
if (is32bit) {
4613+
ret trans_upcall(sub.bcx,
4614+
"upcall_log_float",
4615+
vec(sub.val));
4616+
} else {
4617+
auto tmp = sub.bcx.build.Alloca(tr);
45884618
sub.bcx.build.Store(sub.val, tmp);
4589-
sub = res(sub.bcx, tmp);
4619+
auto v = vp2i(sub.bcx, tmp);
4620+
ret trans_upcall(sub.bcx,
4621+
"upcall_log_double",
4622+
vec(v));
45904623
}
4591-
case(_) { }
45924624
}
45934625

45944626
alt (e_ty.struct) {
@@ -4598,12 +4630,6 @@ fn trans_log(@block_ctxt cx, @ast.expr e) -> result {
45984630
"upcall_log_str",
45994631
vec(v));
46004632
}
4601-
case (ty.ty_float) {
4602-
auto v = vp2i(sub.bcx, sub.val);
4603-
ret trans_upcall(sub.bcx,
4604-
"upcall_log_float",
4605-
vec(v));
4606-
}
46074633
case (_) {
46084634
ret trans_upcall(sub.bcx,
46094635
"upcall_log_int",

src/comp/middle/typeck.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1497,7 +1497,9 @@ fn check_lit(@ast.lit lit) -> @ty.t {
14971497
case (ast.lit_str(_)) { sty = ty.ty_str; }
14981498
case (ast.lit_char(_)) { sty = ty.ty_char; }
14991499
case (ast.lit_int(_)) { sty = ty.ty_int; }
1500-
case (ast.lit_float(_)) { sty = ty.ty_float; }
1500+
case (ast.lit_float(_)) { sty = ty.ty_float; }
1501+
case (ast.lit_mach_float(?tm, _))
1502+
{ sty = ty.ty_machine(tm); }
15011503
case (ast.lit_uint(_)) { sty = ty.ty_uint; }
15021504
case (ast.lit_mach_int(?tm, _)) { sty = ty.ty_machine(tm); }
15031505
case (ast.lit_nil) { sty = ty.ty_nil; }

src/rt/rust_upcall.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,14 @@ void upcall_log_int(rust_task *task, int32_t i) {
4040
}
4141

4242
extern "C" CDECL
43-
void upcall_log_float(rust_task *task, double *f) {
43+
void upcall_log_float(rust_task *task, float f) {
44+
LOG_UPCALL_ENTRY(task);
45+
task->log(rust_log::UPCALL | rust_log::ULOG,
46+
"rust: %12.12f", f);
47+
}
48+
49+
extern "C" CDECL
50+
void upcall_log_double(rust_task *task, double *f) {
4451
LOG_UPCALL_ENTRY(task);
4552
task->log(rust_log::UPCALL | rust_log::ULOG,
4653
"rust: %12.12f", *f);

src/test/run-pass/float2.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
fn main() {
2+
auto a = 1.5e6;
3+
auto b = 1.5E6;
4+
auto c = 1e6;
5+
auto d = 1E6;
6+
auto e = 3.0f32;
7+
auto f = 5.9f64;
8+
auto g = 1.e6f32;
9+
auto h = 1.0e7f64;
10+
auto i = 1.0E7f64;
11+
auto j = 3.1e+9;
12+
auto k = 3.2e-10;
13+
14+
check(a == b);
15+
check(c < b);
16+
check(c == d);
17+
check(e < g);
18+
check(f < h);
19+
check(g == 1000000.0f32);
20+
check(h == i);
21+
check(j > k);
22+
check(k < a);
23+
}

0 commit comments

Comments
 (0)