Get rid of the >>> operator and make >> logical or arithmetic depending on the signedness. Closes #2417.
This commit is contained in:
parent
8d7f3bd1ca
commit
15cef374b9
14 changed files with 49 additions and 79 deletions
|
@ -201,9 +201,8 @@ enum binop {
|
||||||
bitxor,
|
bitxor,
|
||||||
bitand,
|
bitand,
|
||||||
bitor,
|
bitor,
|
||||||
lsl,
|
shl,
|
||||||
lsr,
|
shr,
|
||||||
asr,
|
|
||||||
eq,
|
eq,
|
||||||
lt,
|
lt,
|
||||||
le,
|
le,
|
||||||
|
|
|
@ -72,9 +72,8 @@ fn binop_to_str(op: binop) -> str {
|
||||||
bitxor { ret "^"; }
|
bitxor { ret "^"; }
|
||||||
bitand { ret "&"; }
|
bitand { ret "&"; }
|
||||||
bitor { ret "|"; }
|
bitor { ret "|"; }
|
||||||
lsl { ret "<<"; }
|
shl { ret "<<"; }
|
||||||
lsr { ret ">>"; }
|
shr { ret ">>"; }
|
||||||
asr { ret ">>>"; }
|
|
||||||
eq { ret "=="; }
|
eq { ret "=="; }
|
||||||
lt { ret "<"; }
|
lt { ret "<"; }
|
||||||
le { ret "<="; }
|
le { ret "<="; }
|
||||||
|
@ -90,9 +89,8 @@ pure fn lazy_binop(b: binop) -> bool {
|
||||||
|
|
||||||
pure fn is_shift_binop(b: binop) -> bool {
|
pure fn is_shift_binop(b: binop) -> bool {
|
||||||
alt b {
|
alt b {
|
||||||
lsl { true }
|
shl { true }
|
||||||
lsr { true }
|
shr { true }
|
||||||
asr { true }
|
|
||||||
_ { false }
|
_ { false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -353,7 +351,7 @@ fn operator_prec(op: ast::binop) -> uint {
|
||||||
mul | div | rem { 12u }
|
mul | div | rem { 12u }
|
||||||
// 'as' sits between here with 11
|
// 'as' sits between here with 11
|
||||||
add | subtract { 10u }
|
add | subtract { 10u }
|
||||||
lsl | lsr | asr { 9u }
|
shl | shr { 9u }
|
||||||
bitand { 8u }
|
bitand { 8u }
|
||||||
bitxor { 7u }
|
bitxor { 7u }
|
||||||
bitor { 6u }
|
bitor { 6u }
|
||||||
|
|
|
@ -114,10 +114,8 @@ fn check_restricted_keywords_(p: parser, w: ast::ident) {
|
||||||
fn expect_gt(p: parser) {
|
fn expect_gt(p: parser) {
|
||||||
if p.token == token::GT {
|
if p.token == token::GT {
|
||||||
p.bump();
|
p.bump();
|
||||||
} else if p.token == token::BINOP(token::LSR) {
|
} else if p.token == token::BINOP(token::SHR) {
|
||||||
p.swap(token::GT, p.span.lo + 1u, p.span.hi);
|
p.swap(token::GT, p.span.lo + 1u, p.span.hi);
|
||||||
} else if p.token == token::BINOP(token::ASR) {
|
|
||||||
p.swap(token::BINOP(token::LSR), p.span.lo + 1u, p.span.hi);
|
|
||||||
} else {
|
} else {
|
||||||
let mut s: str = "expecting ";
|
let mut s: str = "expecting ";
|
||||||
s += token_to_str(p.reader, token::GT);
|
s += token_to_str(p.reader, token::GT);
|
||||||
|
@ -132,8 +130,7 @@ fn parse_seq_to_before_gt<T: copy>(sep: option<token::token>,
|
||||||
p: parser) -> [T] {
|
p: parser) -> [T] {
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
let mut v = [];
|
let mut v = [];
|
||||||
while p.token != token::GT && p.token != token::BINOP(token::LSR) &&
|
while p.token != token::GT && p.token != token::BINOP(token::SHR) {
|
||||||
p.token != token::BINOP(token::ASR) {
|
|
||||||
alt sep {
|
alt sep {
|
||||||
some(t) { if first { first = false; } else { expect(p, t); } }
|
some(t) { if first { first = false; } else { expect(p, t); } }
|
||||||
_ { }
|
_ { }
|
||||||
|
|
|
@ -392,7 +392,7 @@ fn next_token_inner(rdr: reader) -> token::token {
|
||||||
rdr.bump();
|
rdr.bump();
|
||||||
alt rdr.curr {
|
alt rdr.curr {
|
||||||
'=' { rdr.bump(); ret token::LE; }
|
'=' { rdr.bump(); ret token::LE; }
|
||||||
'<' { ret binop(rdr, token::LSL); }
|
'<' { ret binop(rdr, token::SHL); }
|
||||||
'-' {
|
'-' {
|
||||||
rdr.bump();
|
rdr.bump();
|
||||||
alt rdr.curr {
|
alt rdr.curr {
|
||||||
|
@ -407,12 +407,7 @@ fn next_token_inner(rdr: reader) -> token::token {
|
||||||
rdr.bump();
|
rdr.bump();
|
||||||
alt rdr.curr {
|
alt rdr.curr {
|
||||||
'=' { rdr.bump(); ret token::GE; }
|
'=' { rdr.bump(); ret token::GE; }
|
||||||
'>' {
|
'>' { ret binop(rdr, token::SHR); }
|
||||||
if rdr.next() == '>' {
|
|
||||||
rdr.bump();
|
|
||||||
ret binop(rdr, token::ASR);
|
|
||||||
} else { ret binop(rdr, token::LSR); }
|
|
||||||
}
|
|
||||||
_ { ret token::GT; }
|
_ { ret token::GT; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1119,9 +1119,8 @@ fn parse_assign_expr(p: parser) -> @expr {
|
||||||
token::CARET { aop = bitxor; }
|
token::CARET { aop = bitxor; }
|
||||||
token::AND { aop = bitand; }
|
token::AND { aop = bitand; }
|
||||||
token::OR { aop = bitor; }
|
token::OR { aop = bitor; }
|
||||||
token::LSL { aop = lsl; }
|
token::SHL { aop = shl; }
|
||||||
token::LSR { aop = lsr; }
|
token::SHR { aop = shr; }
|
||||||
token::ASR { aop = asr; }
|
|
||||||
}
|
}
|
||||||
p.get_id(); // see ast_util::op_expr_callee_id
|
p.get_id(); // see ast_util::op_expr_callee_id
|
||||||
ret mk_expr(p, lo, rhs.span.hi, expr_assign_op(aop, lhs, rhs));
|
ret mk_expr(p, lo, rhs.span.hi, expr_assign_op(aop, lhs, rhs));
|
||||||
|
|
|
@ -25,9 +25,8 @@ fn token_to_binop(tok: token) -> option<ast::binop> {
|
||||||
// 'as' sits between here with 11
|
// 'as' sits between here with 11
|
||||||
BINOP(PLUS) { some(add) }
|
BINOP(PLUS) { some(add) }
|
||||||
BINOP(MINUS) { some(subtract) }
|
BINOP(MINUS) { some(subtract) }
|
||||||
BINOP(LSL) { some(lsl) }
|
BINOP(SHL) { some(shl) }
|
||||||
BINOP(LSR) { some(lsr) }
|
BINOP(SHR) { some(shr) }
|
||||||
BINOP(ASR) { some(asr) }
|
|
||||||
BINOP(AND) { some(bitand) }
|
BINOP(AND) { some(bitand) }
|
||||||
BINOP(CARET) { some(bitxor) }
|
BINOP(CARET) { some(bitxor) }
|
||||||
BINOP(OR) { some(bitor) }
|
BINOP(OR) { some(bitor) }
|
||||||
|
|
|
@ -14,9 +14,8 @@ enum binop {
|
||||||
CARET,
|
CARET,
|
||||||
AND,
|
AND,
|
||||||
OR,
|
OR,
|
||||||
LSL,
|
SHL,
|
||||||
LSR,
|
SHR,
|
||||||
ASR,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum token {
|
enum token {
|
||||||
|
@ -78,9 +77,8 @@ fn binop_to_str(o: binop) -> str {
|
||||||
CARET { ret "^"; }
|
CARET { ret "^"; }
|
||||||
AND { ret "&"; }
|
AND { ret "&"; }
|
||||||
OR { ret "|"; }
|
OR { ret "|"; }
|
||||||
LSL { ret "<<"; }
|
SHL { ret "<<"; }
|
||||||
LSR { ret ">>"; }
|
SHR { ret ">>"; }
|
||||||
ASR { ret ">>>"; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,7 @@ fn eval_const_expr(tcx: middle::ty::ctxt, e: @expr) -> const_val {
|
||||||
mul { const_int(a * b) } div { const_int(a / b) }
|
mul { const_int(a * b) } div { const_int(a / b) }
|
||||||
rem { const_int(a % b) } and | bitand { const_int(a & b) }
|
rem { const_int(a % b) } and | bitand { const_int(a & b) }
|
||||||
or | bitor { const_int(a | b) } bitxor { const_int(a ^ b) }
|
or | bitor { const_int(a | b) } bitxor { const_int(a ^ b) }
|
||||||
lsl { const_int(a << b) } lsr { const_int(a >> b) }
|
shl { const_int(a << b) } shr { const_int(a >> b) }
|
||||||
asr { const_int(a >>> b) }
|
|
||||||
eq { fromb(a == b) } lt { fromb(a < b) }
|
eq { fromb(a == b) } lt { fromb(a < b) }
|
||||||
le { fromb(a <= b) } ne { fromb(a != b) }
|
le { fromb(a <= b) } ne { fromb(a != b) }
|
||||||
ge { fromb(a >= b) } gt { fromb(a > b) }
|
ge { fromb(a >= b) } gt { fromb(a > b) }
|
||||||
|
@ -58,9 +57,7 @@ fn eval_const_expr(tcx: middle::ty::ctxt, e: @expr) -> const_val {
|
||||||
mul { const_uint(a * b) } div { const_uint(a / b) }
|
mul { const_uint(a * b) } div { const_uint(a / b) }
|
||||||
rem { const_uint(a % b) } and | bitand { const_uint(a & b) }
|
rem { const_uint(a % b) } and | bitand { const_uint(a & b) }
|
||||||
or | bitor { const_uint(a | b) } bitxor { const_uint(a ^ b) }
|
or | bitor { const_uint(a | b) } bitxor { const_uint(a ^ b) }
|
||||||
lsl { const_int((a << b) as i64) }
|
shl { const_uint(a << b) } shr { const_uint(a >> b) }
|
||||||
lsr { const_int((a >> b) as i64) }
|
|
||||||
asr { const_int((a >>> b) as i64) }
|
|
||||||
eq { fromb(a == b) } lt { fromb(a < b) }
|
eq { fromb(a == b) } lt { fromb(a < b) }
|
||||||
le { fromb(a <= b) } ne { fromb(a != b) }
|
le { fromb(a <= b) } ne { fromb(a != b) }
|
||||||
ge { fromb(a >= b) } gt { fromb(a > b) }
|
ge { fromb(a >= b) } gt { fromb(a > b) }
|
||||||
|
|
|
@ -1617,9 +1617,12 @@ fn trans_eager_binop(cx: block, op: ast::binop, lhs: ValueRef,
|
||||||
ast::bitor { Or(cx, lhs, rhs) }
|
ast::bitor { Or(cx, lhs, rhs) }
|
||||||
ast::bitand { And(cx, lhs, rhs) }
|
ast::bitand { And(cx, lhs, rhs) }
|
||||||
ast::bitxor { Xor(cx, lhs, rhs) }
|
ast::bitxor { Xor(cx, lhs, rhs) }
|
||||||
ast::lsl { Shl(cx, lhs, rhs) }
|
ast::shl { Shl(cx, lhs, rhs) }
|
||||||
ast::lsr { LShr(cx, lhs, rhs) }
|
ast::shr {
|
||||||
ast::asr { AShr(cx, lhs, rhs) }
|
if ty::type_is_signed(intype) {
|
||||||
|
AShr(cx, lhs, rhs)
|
||||||
|
} else { LShr(cx, lhs, rhs) }
|
||||||
|
}
|
||||||
_ {
|
_ {
|
||||||
let cmpr = trans_compare(cx, op, lhs, lhs_t, rhs, rhs_t);
|
let cmpr = trans_compare(cx, op, lhs, lhs_t, rhs, rhs_t);
|
||||||
cx = cmpr.bcx;
|
cx = cmpr.bcx;
|
||||||
|
@ -4565,9 +4568,11 @@ fn trans_const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
|
||||||
ast::bitxor { llvm::LLVMConstXor(te1, te2) }
|
ast::bitxor { llvm::LLVMConstXor(te1, te2) }
|
||||||
ast::bitand { llvm::LLVMConstAnd(te1, te2) }
|
ast::bitand { llvm::LLVMConstAnd(te1, te2) }
|
||||||
ast::bitor { llvm::LLVMConstOr(te1, te2) }
|
ast::bitor { llvm::LLVMConstOr(te1, te2) }
|
||||||
ast::lsl { llvm::LLVMConstShl(te1, te2) }
|
ast::shl { llvm::LLVMConstShl(te1, te2) }
|
||||||
ast::lsr { llvm::LLVMConstLShr(te1, te2) }
|
ast::shr {
|
||||||
ast::asr { llvm::LLVMConstAShr(te1, te2) }
|
if signed { llvm::LLVMConstAShr(te1, te2) }
|
||||||
|
else { llvm::LLVMConstLShr(te1, te2) }
|
||||||
|
}
|
||||||
ast::eq |
|
ast::eq |
|
||||||
ast::lt |
|
ast::lt |
|
||||||
ast::le |
|
ast::le |
|
||||||
|
|
|
@ -2704,9 +2704,8 @@ fn is_binopable(_cx: ctxt, ty: t, op: ast::binop) -> bool {
|
||||||
ast::bitxor { opcat_bit }
|
ast::bitxor { opcat_bit }
|
||||||
ast::bitand { opcat_bit }
|
ast::bitand { opcat_bit }
|
||||||
ast::bitor { opcat_bit }
|
ast::bitor { opcat_bit }
|
||||||
ast::lsl { opcat_shift }
|
ast::shl { opcat_shift }
|
||||||
ast::lsr { opcat_shift }
|
ast::shr { opcat_shift }
|
||||||
ast::asr { opcat_shift }
|
|
||||||
ast::eq { opcat_eq }
|
ast::eq { opcat_eq }
|
||||||
ast::ne { opcat_eq }
|
ast::ne { opcat_eq }
|
||||||
ast::lt { opcat_rel }
|
ast::lt { opcat_rel }
|
||||||
|
|
|
@ -867,8 +867,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||||
fn binop_method(op: ast::binop) -> option<str> {
|
fn binop_method(op: ast::binop) -> option<str> {
|
||||||
alt op {
|
alt op {
|
||||||
ast::add | ast::subtract | ast::mul | ast::div | ast::rem |
|
ast::add | ast::subtract | ast::mul | ast::div | ast::rem |
|
||||||
ast::bitxor | ast::bitand | ast::bitor | ast::lsl | ast::lsr |
|
ast::bitxor | ast::bitand | ast::bitor | ast::shl | ast::shr
|
||||||
ast::asr { some(ast_util::binop_to_str(op)) }
|
{ some(ast_util::binop_to_str(op)) }
|
||||||
_ { none }
|
_ { none }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,6 @@ fn test_char() {
|
||||||
assert (ch10 / ch4 == ch2);
|
assert (ch10 / ch4 == ch2);
|
||||||
assert (ch10 % ch4 == ch2);
|
assert (ch10 % ch4 == ch2);
|
||||||
assert (ch10 >> ch2 == ch2);
|
assert (ch10 >> ch2 == ch2);
|
||||||
assert (ch10 >>> ch2 == ch2);
|
|
||||||
assert (ch10 << ch4 == 160 as char);
|
assert (ch10 << ch4 == 160 as char);
|
||||||
assert (ch10 | ch4 == 14 as char);
|
assert (ch10 | ch4 == 14 as char);
|
||||||
assert (ch10 & ch2 == ch2);
|
assert (ch10 & ch2 == ch2);
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
|
|
||||||
#[cfg(target_arch = "x86")]
|
#[cfg(target_arch = "x86")]
|
||||||
fn target() {
|
fn target() {
|
||||||
assert (-1000 >> 3 == 536870787);
|
assert (-1000 as uint >> 3u == 536870787u);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
fn target() {
|
fn target() {
|
||||||
assert (-1000 >> 3 == 2305843009213693827);
|
assert (-1000 as uint >> 3u == 2305843009213693827u);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn general() {
|
fn general() {
|
||||||
|
@ -24,7 +24,7 @@ fn general() {
|
||||||
assert (0xf0 | 0xf == 0xff);
|
assert (0xf0 | 0xf == 0xff);
|
||||||
assert (0xf << 4 == 0xf0);
|
assert (0xf << 4 == 0xf0);
|
||||||
assert (0xf0 >> 4 == 0xf);
|
assert (0xf0 >> 4 == 0xf);
|
||||||
assert (-16 >>> 2 == -4);
|
assert (-16 >> 2 == -4);
|
||||||
assert (0b1010_1010 | 0b0101_0101 == 0xff);
|
assert (0b1010_1010 | 0b0101_0101 == 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,71 +16,56 @@ fn test_expr() {
|
||||||
let v4 = 4 as u8;
|
let v4 = 4 as u8;
|
||||||
let v2 = 2 as u8;
|
let v2 = 2 as u8;
|
||||||
assert (v10 >> v2 == v2 as uint);
|
assert (v10 >> v2 == v2 as uint);
|
||||||
assert (v10 >>> v2 == v2 as uint);
|
|
||||||
assert (v10 << v4 == 160 as uint);
|
assert (v10 << v4 == 160 as uint);
|
||||||
|
|
||||||
let v10 = 10 as u8;
|
let v10 = 10 as u8;
|
||||||
let v4 = 4 as uint;
|
let v4 = 4 as uint;
|
||||||
let v2 = 2 as uint;
|
let v2 = 2 as uint;
|
||||||
assert (v10 >> v2 == v2 as u8);
|
assert (v10 >> v2 == v2 as u8);
|
||||||
assert (v10 >>> v2 == v2 as u8);
|
|
||||||
assert (v10 << v4 == 160 as u8);
|
assert (v10 << v4 == 160 as u8);
|
||||||
|
|
||||||
let v10 = 10 as int;
|
let v10 = 10 as int;
|
||||||
let v4 = 4 as i8;
|
let v4 = 4 as i8;
|
||||||
let v2 = 2 as i8;
|
let v2 = 2 as i8;
|
||||||
assert (v10 >> v2 == v2 as int);
|
assert (v10 >> v2 == v2 as int);
|
||||||
assert (v10 >>> v2 == v2 as int);
|
|
||||||
assert (v10 << v4 == 160 as int);
|
assert (v10 << v4 == 160 as int);
|
||||||
|
|
||||||
let v10 = 10 as i8;
|
let v10 = 10 as i8;
|
||||||
let v4 = 4 as int;
|
let v4 = 4 as int;
|
||||||
let v2 = 2 as int;
|
let v2 = 2 as int;
|
||||||
assert (v10 >> v2 == v2 as i8);
|
assert (v10 >> v2 == v2 as i8);
|
||||||
assert (v10 >>> v2 == v2 as i8);
|
|
||||||
assert (v10 << v4 == 160 as i8);
|
assert (v10 << v4 == 160 as i8);
|
||||||
|
|
||||||
let v10 = 10 as uint;
|
let v10 = 10 as uint;
|
||||||
let v4 = 4 as int;
|
let v4 = 4 as int;
|
||||||
let v2 = 2 as int;
|
let v2 = 2 as int;
|
||||||
assert (v10 >> v2 == v2 as uint);
|
assert (v10 >> v2 == v2 as uint);
|
||||||
assert (v10 >>> v2 == v2 as uint);
|
|
||||||
assert (v10 << v4 == 160 as uint);
|
assert (v10 << v4 == 160 as uint);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_const() {
|
fn test_const() {
|
||||||
const r1_1: uint = 10u >> 2u8;
|
const r1_1: uint = 10u >> 2u8;
|
||||||
const r2_1: uint = 10u >>> 2u8;
|
const r2_1: uint = 10u << 4u8;
|
||||||
const r3_1: uint = 10u << 4u8;
|
|
||||||
assert r1_1 == 2 as uint;
|
assert r1_1 == 2 as uint;
|
||||||
assert r2_1 == 2 as uint;
|
assert r2_1 == 160 as uint;
|
||||||
assert r3_1 == 160 as uint;
|
|
||||||
|
|
||||||
const r1_2: u8 = 10u8 >> 2u;
|
const r1_2: u8 = 10u8 >> 2u;
|
||||||
const r2_2: u8 = 10u8 >>> 2u;
|
const r2_2: u8 = 10u8 << 4u;
|
||||||
const r3_2: u8 = 10u8 << 4u;
|
|
||||||
assert r1_2 == 2 as u8;
|
assert r1_2 == 2 as u8;
|
||||||
assert r2_2 == 2 as u8;
|
assert r2_2 == 160 as u8;
|
||||||
assert r3_2 == 160 as u8;
|
|
||||||
|
|
||||||
const r1_3: int = 10 >> 2i8;
|
const r1_3: int = 10 >> 2i8;
|
||||||
const r2_3: int = 10 >>> 2i8;
|
const r2_3: int = 10 << 4i8;
|
||||||
const r3_3: int = 10 << 4i8;
|
|
||||||
assert r1_3 == 2 as int;
|
assert r1_3 == 2 as int;
|
||||||
assert r2_3 == 2 as int;
|
assert r2_3 == 160 as int;
|
||||||
assert r3_3 == 160 as int;
|
|
||||||
|
|
||||||
const r1_4: i8 = 10i8 >> 2;
|
const r1_4: i8 = 10i8 >> 2;
|
||||||
const r2_4: i8 = 10i8 >>> 2;
|
const r2_4: i8 = 10i8 << 4;
|
||||||
const r3_4: i8 = 10i8 << 4;
|
|
||||||
assert r1_4 == 2 as i8;
|
assert r1_4 == 2 as i8;
|
||||||
assert r2_4 == 2 as i8;
|
assert r2_4 == 160 as i8;
|
||||||
assert r3_4 == 160 as i8;
|
|
||||||
|
|
||||||
const r1_5: uint = 10u >> 2i8;
|
const r1_5: uint = 10u >> 2i8;
|
||||||
const r2_5: uint = 10u >>> 2i8;
|
const r2_5: uint = 10u << 4i8;
|
||||||
const r3_5: uint = 10u << 4i8;
|
|
||||||
assert r1_5 == 2 as uint;
|
assert r1_5 == 2 as uint;
|
||||||
assert r2_5 == 2 as uint;
|
assert r2_5 == 160 as uint;
|
||||||
assert r3_5 == 160 as uint;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue