Add a new AST node for unsuffixed integer types.

This commit is contained in:
Lindsey Kuper 2012-06-11 16:31:03 -07:00
parent baf58a764b
commit 8467279fac
9 changed files with 65 additions and 38 deletions

View File

@ -402,6 +402,7 @@ enum lit_ {
lit_str(str),
lit_int(i64, int_ty),
lit_uint(u64, uint_ty),
lit_int_unsuffixed(i64, int_ty),
lit_float(str, float_ty),
lit_nil,
lit_bool(bool),

View File

@ -51,7 +51,14 @@ fn need_parens(expr: @ast::expr, outer_prec: uint) -> bool {
fn ends_in_lit_int(ex: @ast::expr) -> bool {
alt ex.node {
ast::expr_lit(@{node: ast::lit_int(_, ast::ty_i), _}) { true }
ast::expr_lit(node) {
alt node {
@{node: ast::lit_int(_, ast::ty_i), _} |
@{node: ast::lit_int_unsuffixed(_, ast::ty_i), _}
{ true }
_ { false }
}
}
ast::expr_binary(_, _, sub) | ast::expr_unary(_, sub) |
ast::expr_move(_, sub) | ast::expr_copy(sub) |
ast::expr_assign(_, sub) |

View File

@ -282,7 +282,10 @@ fn scan_number(c: char, rdr: reader) -> token::token {
rdr.fatal("no valid digits found for number");
}
let parsed = option::get(u64::from_str_radix(num_str, base as u64));
ret token::LIT_INT(parsed as i64, ast::ty_i);
#debug["lexing %s as an unsuffixed integer literal",
num_str];
ret token::LIT_INT_UNSUFFIXED(parsed as i64, ast::ty_i);
}
}

View File

@ -507,7 +507,7 @@ class parser {
let lo = self.span.lo;
self.bump();
alt copy self.token {
token::LIT_INT(num, ty_i) {
token::LIT_INT_UNSUFFIXED(num, _) {
self.bump();
some(mac_var(num as uint))
}
@ -519,7 +519,7 @@ class parser {
some(mac_aq(mk_sp(lo,hi), e))
}
_ {
self.fatal("expected `(` or integer literal");
self.fatal("expected `(` or unsuffixed integer literal");
}
}
}
@ -540,7 +540,7 @@ class parser {
token::UNDERSCORE {
self.bump(); some(vstore_fixed(none))
}
token::LIT_INT(i, ty_i) if i >= 0i64 {
token::LIT_INT_UNSUFFIXED(i, _) if i >= 0i64 {
self.bump(); some(vstore_fixed(some(i as uint)))
}
token::BINOP(token::AND) {
@ -559,6 +559,7 @@ class parser {
alt tok {
token::LIT_INT(i, it) { lit_int(i, it) }
token::LIT_UINT(u, ut) { lit_uint(u, ut) }
token::LIT_INT_UNSUFFIXED(i, it) { lit_int_unsuffixed(i, it) }
token::LIT_FLOAT(s, ft) { lit_float(self.get_str(s), ft) }
token::LIT_STR(s) { lit_str(self.get_str(s)) }
token::LPAREN { self.expect(token::RPAREN); lit_nil }

View File

@ -58,6 +58,7 @@ enum token {
/* Literals */
LIT_INT(i64, ast::int_ty),
LIT_UINT(u64, ast::uint_ty),
LIT_INT_UNSUFFIXED(i64, ast::int_ty),
LIT_FLOAT(str_num, ast::float_ty),
LIT_STR(str_num),
@ -132,6 +133,9 @@ fn to_str(in: interner<@str>, t: token) -> str {
LIT_UINT(u, t) {
ret uint::to_str(u as uint, 10u) + ast_util::uint_ty_to_str(t);
}
LIT_INT_UNSUFFIXED(i, t) {
ret int::to_str(i as int, 10u) + ast_util::int_ty_to_str(t);
}
LIT_FLOAT(s, t) {
ret *interner::get(in, s) +
ast_util::float_ty_to_str(t);
@ -161,6 +165,7 @@ pure fn can_begin_expr(t: token) -> bool {
TILDE { true }
LIT_INT(_, _) { true }
LIT_UINT(_, _) { true }
LIT_INT_UNSUFFIXED(_, _) { true }
LIT_FLOAT(_, _) { true }
LIT_STR(_) { true }
POUND { true }
@ -178,6 +183,7 @@ fn is_lit(t: token::token) -> bool {
ret alt t {
token::LIT_INT(_, _) { true }
token::LIT_UINT(_, _) { true }
token::LIT_INT_UNSUFFIXED(_, _) { true }
token::LIT_FLOAT(_, _) { true }
token::LIT_STR(_) { true }
_ { false }

View File

@ -1628,6 +1628,17 @@ fn print_literal(s: ps, &&lit: @ast::lit) {
u64::to_str(u, 10u)
+ ast_util::uint_ty_to_str(t));
}
ast::lit_int_unsuffixed(i, t) {
if i < 0_i64 {
word(s.s,
"-" + u64::to_str(-i as u64, 10u)
+ ast_util::int_ty_to_str(t));
} else {
word(s.s,
u64::to_str(i as u64, 10u)
+ ast_util::int_ty_to_str(t));
}
}
ast::lit_float(f, t) {
word(s.s, f + ast_util::float_ty_to_str(t));
}

View File

@ -111,6 +111,7 @@ fn lit_to_const(lit: @lit) -> const_val {
lit_str(s) { const_str(s) }
lit_int(n, _) { const_int(n) }
lit_uint(n, _) { const_uint(n) }
lit_int_unsuffixed(n, _) { const_int(n) }
lit_float(n, _) { const_float(option::get(float::from_str(n)) as f64) }
lit_nil { const_int(0i64) }
lit_bool(b) { const_int(b as i64) }

View File

@ -1483,6 +1483,11 @@ fn trans_crate_lit(cx: @crate_ctxt, lit: ast::lit) -> ValueRef {
alt lit.node {
ast::lit_int(i, t) { C_integral(T_int_ty(cx, t), i as u64, True) }
ast::lit_uint(u, t) { C_integral(T_uint_ty(cx, t), u, False) }
ast::lit_int_unsuffixed(i, t) {
// FIXME (#1425): should we be using cx.fcx.infcx to figure out what
// to actually generate from this?
C_integral(T_int_ty(cx, t), i as u64, True)
}
ast::lit_float(fs, t) { C_floating(fs, T_float_ty(cx, t)) }
ast::lit_bool(b) { C_bool(b) }
ast::lit_nil { C_nil() }

View File

@ -629,40 +629,32 @@ fn check_lit(fcx: @fn_ctxt, lit: @ast::lit) -> ty::t {
alt lit.node {
ast::lit_str(_) { ty::mk_str(tcx) }
ast::lit_int(v, t) {
alt t {
ty_char | ty_i8 | ty_i16 | ty_i32 | ty_i64 {
// If it's a char or has an explicit suffix, give it the
// appropriate integral type.
ty::mk_mach_int(tcx, t)
}
ty_i {
// Otherwise, an unsuffixed integer literal parses to a
// `ty_i`. In that case, it could have any integral type,
// so create an integral type variable for it.
let vid = fcx.infcx.next_ty_var_integral_id();
// We need to sniff at the value `v` provided and figure
// out how big of an int it is; that determines the set of
// possibly types it could take on.
let possible_types = alt v {
0i64 to 127i64 { min_8bit_tys() }
128i64 to 65535i64 { min_16bit_tys() }
65536i64 to 4294967295i64 { min_32bit_tys() }
_ { min_64bit_tys() }
};
// Store the set of possible types
fcx.infcx.set(fcx.infcx.tvib, vid,
root(possible_types));
ty::mk_var_integral(tcx, vid);
// FIXME: remove me when #1425 is finished.
ty::mk_mach_int(tcx, t)
}
}
}
ast::lit_int(_, t) { ty::mk_mach_int(tcx, t) }
ast::lit_uint(_, t) { ty::mk_mach_uint(tcx, t) }
ast::lit_int_unsuffixed(v, t) {
// An unsuffixed integer literal could have any integral type,
// so we create an integral type variable for it.
let vid = fcx.infcx.next_ty_var_integral_id();
// We need to sniff at the value `v` and figure out how big of
// an int it is; that determines the range of possible types
// that the integral type variable could take on.
let possible_types = alt v {
0i64 to 127i64 { min_8bit_tys() }
128i64 to 65535i64 { min_16bit_tys() }
65536i64 to 4294967295i64 { min_32bit_tys() }
_ { min_64bit_tys() }
};
// Store the set of possible types and return the integral
// type variable.
fcx.infcx.set(fcx.infcx.tvib, vid,
root(possible_types));
ty::mk_var_integral(tcx, vid);
// FIXME: remove me when #1425 is finished.
ty::mk_mach_int(tcx, t)
}
ast::lit_float(_, t) { ty::mk_mach_float(tcx, t) }
ast::lit_nil { ty::mk_nil(tcx) }
ast::lit_bool(_) { ty::mk_bool(tcx) }