Check and translate 'as' cast-operator, lower target-specific types, reindent rustc.rs, enable uint test.

This commit is contained in:
Graydon Hoare 2010-11-22 16:27:00 -08:00
parent c262543d3b
commit d3cb25d5d1
5 changed files with 229 additions and 81 deletions

View file

@ -551,18 +551,36 @@ impure fn trans_lit(@block_ctxt cx, &ast.lit lit) -> result {
}
}
fn node_type(@crate_ctxt cx, &ast.ann a) -> TypeRef {
fn target_type(@crate_ctxt cx, @typeck.ty t) -> @typeck.ty {
alt (t.struct) {
case (typeck.ty_int) {
auto tm = typeck.ty_machine(cx.sess.get_targ_cfg().int_type);
ret @rec(struct=tm with *t);
}
case (typeck.ty_uint) {
auto tm = typeck.ty_machine(cx.sess.get_targ_cfg().uint_type);
ret @rec(struct=tm with *t);
}
}
ret t;
}
fn node_ann_type(@crate_ctxt cx, &ast.ann a) -> @typeck.ty {
alt (a) {
case (ast.ann_none) {
log "missing type annotation";
fail;
}
case (ast.ann_type(?t)) {
ret type_of(cx, t);
ret target_type(cx, t);
}
}
}
fn node_type(@crate_ctxt cx, &ast.ann a) -> TypeRef {
ret type_of(cx, node_ann_type(cx, a));
}
impure fn trans_unary(@block_ctxt cx, ast.unop op,
&ast.expr e, &ast.ann a) -> result {
@ -962,6 +980,36 @@ impure fn trans_expr(@block_ctxt cx, &ast.expr e) -> result {
args_res._0.build.FastCall(f_res._0.val, llargs));
}
case (ast.expr_cast(?e, _, ?ann)) {
auto e_res = trans_expr(cx, *e);
auto llsrctype = val_ty(e_res.val);
auto t = node_ann_type(cx.fcx.ccx, ann);
auto lldsttype = type_of(cx.fcx.ccx, t);
if (!typeck.type_is_fp(t)) {
if (llvm.LLVMGetIntTypeWidth(lldsttype) >
llvm.LLVMGetIntTypeWidth(llsrctype)) {
if (typeck.type_is_signed(t)) {
// Widening signed cast.
e_res.val =
e_res.bcx.build.SExtOrBitCast(e_res.val,
lldsttype);
} else {
// Widening unsigned cast.
e_res.val =
e_res.bcx.build.ZExtOrBitCast(e_res.val,
lldsttype);
}
} else {
// Narrowing cast.
e_res.val =
e_res.bcx.build.TruncOrBitCast(e_res.val,
lldsttype);
}
} else {
cx.fcx.ccx.sess.unimpl("fp cast");
}
ret e_res;
}
}
cx.fcx.ccx.sess.unimpl("expr variant in trans_expr");
fail;

View file

@ -391,6 +391,44 @@ fn mode_is_alias(ast.mode m) -> bool {
}
}
fn type_is_scalar(@ty t) -> bool {
alt (t.struct) {
case (ty_bool) { ret true; }
case (ty_int) { ret true; }
case (ty_uint) { ret true; }
case (ty_machine(_)) { ret true; }
case (ty_char) { ret true; }
}
ret false;
}
fn type_is_fp(@ty t) -> bool {
alt (t.struct) {
case (ty_machine(?tm)) {
alt (tm) {
case (common.ty_f32) { ret true; }
case (common.ty_f64) { ret true; }
}
}
}
ret false;
}
fn type_is_signed(@ty t) -> bool {
alt (t.struct) {
case (ty_int) { ret true; }
case (ty_machine(?tm)) {
alt (tm) {
case (common.ty_i8) { ret true; }
case (common.ty_i16) { ret true; }
case (common.ty_i32) { ret true; }
case (common.ty_i64) { ret true; }
}
}
}
ret false;
}
fn plain_ty(&sty st) -> @ty {
ret @rec(struct=st, cname=none[str]);
}
@ -873,6 +911,23 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
ast.ann_type(ret_t)));
}
case (ast.expr_cast(?e, ?t, _)) {
auto e_1 = check_expr(fcx, e);
auto t_1 = ast_ty_to_ty_crate(fcx.ccx, t);
// FIXME: there are more forms of cast to support, eventually.
if (! (type_is_scalar(expr_ty(e_1)) &&
type_is_scalar(t_1))) {
fcx.ccx.sess.span_err(expr.span,
"non-scalar cast: "
+ ty_to_str(expr_ty(e_1))
+ " as "
+ ty_to_str(t_1));
}
ret @fold.respan[ast.expr_](expr.span,
ast.expr_cast(e_1, t,
ast.ann_type(t_1)));
}
case (_) {
// TODO
ret expr;