aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile3
-rw-r--r--src/comp/front/ast.rs1
-rw-r--r--src/comp/front/lexer.rs75
-rw-r--r--src/comp/front/parser.rs4
-rw-r--r--src/comp/front/token.rs1
-rw-r--r--src/comp/middle/trans.rs54
-rw-r--r--src/comp/middle/typeck.rs4
-rw-r--r--src/rt/rust_upcall.cpp9
-rw-r--r--src/test/run-pass/float2.rs23
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