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).
This commit is contained in:
parent
d56971d5b4
commit
23e23bd762
10 changed files with 153 additions and 26 deletions
|
@ -486,7 +486,8 @@ rustllvm/%.o: rustllvm/%.cpp $(MKFILES)
|
|||
|
||||
# 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.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,19 +442,56 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impure fn next_token(reader rdr) -> token.token {
|
||||
auto accum_str = "";
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
@ -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);
|
||||
if (ty.type_is_fp(e_ty)) {
|
||||
let TypeRef tr;
|
||||
let bool is32bit = false;
|
||||
alt (e_ty.struct) {
|
||||
case(ty.ty_float) {
|
||||
auto tmp = sub.bcx.build.Alloca(T_float());
|
||||
sub.bcx.build.Store(sub.val, tmp);
|
||||
sub = res(sub.bcx, tmp);
|
||||
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);
|
||||
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",
|
||||
|
|
|
@ -1498,6 +1498,8 @@ fn check_lit(@ast.lit lit) -> @ty.t {
|
|||
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_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; }
|
||||
|
|
|
@ -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);
|
||||
|
|
23
src/test/run-pass/float2.rs
Normal file
23
src/test/run-pass/float2.rs
Normal file
|
@ -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);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue