Use operator names for operator methods
The methods used to implement operators now simply use the name of the operator itself, except for unary -, which is called min to not clash with binary -. Index is called []. Closes #1520
This commit is contained in:
parent
3aed4b04ce
commit
6bead0e4cc
4 changed files with 40 additions and 35 deletions
|
@ -2219,8 +2219,8 @@ fn trans_assign_op(bcx: @block_ctxt, ex: @ast::expr, op: ast::binop,
|
||||||
let fty = ty::node_id_to_monotype(bcx_tcx(bcx), callee_id);
|
let fty = ty::node_id_to_monotype(bcx_tcx(bcx), callee_id);
|
||||||
ret trans_call_inner(bcx, fty, {|bcx|
|
ret trans_call_inner(bcx, fty, {|bcx|
|
||||||
// FIXME provide the already-computed address, not the expr
|
// FIXME provide the already-computed address, not the expr
|
||||||
trans_impl::trans_method_callee(bcx, callee_id, src, origin)
|
trans_impl::trans_method_callee(bcx, callee_id, dst, origin)
|
||||||
}, [dst], ex.id, save_in(lhs_res.val));
|
}, [src], ex.id, save_in(lhs_res.val));
|
||||||
}
|
}
|
||||||
_ {}
|
_ {}
|
||||||
}
|
}
|
||||||
|
@ -2333,16 +2333,16 @@ fn trans_lazy_binop(bcx: @block_ctxt, op: ast::binop, a: @ast::expr,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn trans_binary(bcx: @block_ctxt, op: ast::binop, a: @ast::expr,
|
fn trans_binary(bcx: @block_ctxt, op: ast::binop, lhs: @ast::expr,
|
||||||
b: @ast::expr, dest: dest, ex: @ast::expr) -> @block_ctxt {
|
rhs: @ast::expr, dest: dest, ex: @ast::expr) -> @block_ctxt {
|
||||||
// User-defined operators
|
// User-defined operators
|
||||||
alt bcx_ccx(bcx).method_map.find(ex.id) {
|
alt bcx_ccx(bcx).method_map.find(ex.id) {
|
||||||
some(origin) {
|
some(origin) {
|
||||||
let callee_id = ast_util::op_expr_callee_id(ex);
|
let callee_id = ast_util::op_expr_callee_id(ex);
|
||||||
let fty = ty::node_id_to_monotype(bcx_tcx(bcx), callee_id);
|
let fty = ty::node_id_to_monotype(bcx_tcx(bcx), callee_id);
|
||||||
ret trans_call_inner(bcx, fty, {|bcx|
|
ret trans_call_inner(bcx, fty, {|bcx|
|
||||||
trans_impl::trans_method_callee(bcx, callee_id, a, origin)
|
trans_impl::trans_method_callee(bcx, callee_id, lhs, origin)
|
||||||
}, [b], ex.id, dest);
|
}, [rhs], ex.id, dest);
|
||||||
}
|
}
|
||||||
_ {}
|
_ {}
|
||||||
}
|
}
|
||||||
|
@ -2350,15 +2350,15 @@ fn trans_binary(bcx: @block_ctxt, op: ast::binop, a: @ast::expr,
|
||||||
// First couple cases are lazy:
|
// First couple cases are lazy:
|
||||||
alt op {
|
alt op {
|
||||||
ast::and | ast::or {
|
ast::and | ast::or {
|
||||||
ret trans_lazy_binop(bcx, op, a, b, dest);
|
ret trans_lazy_binop(bcx, op, lhs, rhs, dest);
|
||||||
}
|
}
|
||||||
_ {
|
_ {
|
||||||
// Remaining cases are eager:
|
// Remaining cases are eager:
|
||||||
let lhs = trans_temp_expr(bcx, a);
|
let lhs_res = trans_temp_expr(bcx, lhs);
|
||||||
let rhs = trans_temp_expr(lhs.bcx, b);
|
let rhs_res = trans_temp_expr(lhs_res.bcx, rhs);
|
||||||
ret trans_eager_binop(rhs.bcx, op, lhs.val,
|
ret trans_eager_binop(rhs_res.bcx, op, lhs_res.val,
|
||||||
ty::expr_ty(bcx_tcx(bcx), a), rhs.val,
|
ty::expr_ty(bcx_tcx(bcx), lhs), rhs_res.val,
|
||||||
ty::expr_ty(bcx_tcx(bcx), b), dest);
|
ty::expr_ty(bcx_tcx(bcx), rhs), dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3517,8 +3517,8 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
|
||||||
ast::expr_tup(args) { ret trans_tup(bcx, args, e.id, dest); }
|
ast::expr_tup(args) { ret trans_tup(bcx, args, e.id, dest); }
|
||||||
ast::expr_lit(lit) { ret trans_lit(bcx, *lit, dest); }
|
ast::expr_lit(lit) { ret trans_lit(bcx, *lit, dest); }
|
||||||
ast::expr_vec(args, _) { ret tvec::trans_vec(bcx, args, e.id, dest); }
|
ast::expr_vec(args, _) { ret tvec::trans_vec(bcx, args, e.id, dest); }
|
||||||
ast::expr_binary(op, x, y) {
|
ast::expr_binary(op, lhs, rhs) {
|
||||||
ret trans_binary(bcx, op, x, y, dest, e);
|
ret trans_binary(bcx, op, lhs, rhs, dest, e);
|
||||||
}
|
}
|
||||||
ast::expr_unary(op, x) {
|
ast::expr_unary(op, x) {
|
||||||
assert op != ast::deref; // lvals are handled above
|
assert op != ast::deref; // lvals are handled above
|
||||||
|
|
|
@ -1768,17 +1768,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
||||||
|
|
||||||
fn binop_method(op: ast::binop) -> option::t<str> {
|
fn binop_method(op: ast::binop) -> option::t<str> {
|
||||||
alt op {
|
alt op {
|
||||||
ast::add { some("op_add") }
|
ast::add | ast::subtract | ast::mul | ast::div | ast::rem |
|
||||||
ast::subtract { some("op_sub") }
|
ast::bitxor | ast::bitand | ast::bitor | ast::lsl | ast::lsr |
|
||||||
ast::mul { some("op_mul") }
|
ast::asr { some(ast_util::binop_to_str(op)) }
|
||||||
ast::div { some("op_div") }
|
|
||||||
ast::rem { some("op_rem") }
|
|
||||||
ast::bitxor { some("op_xor") }
|
|
||||||
ast::bitand { some("op_and") }
|
|
||||||
ast::bitor { some("op_or") }
|
|
||||||
ast::lsl { some("op_shift_left") }
|
|
||||||
ast::lsr { some("op_shift_right") }
|
|
||||||
ast::asr { some("op_ashift_right") }
|
|
||||||
_ { none }
|
_ { none }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1904,14 +1896,14 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
||||||
oper_t = structurally_resolved_type(fcx, oper.span, oper_t);
|
oper_t = structurally_resolved_type(fcx, oper.span, oper_t);
|
||||||
if !(ty::type_is_integral(tcx, oper_t) ||
|
if !(ty::type_is_integral(tcx, oper_t) ||
|
||||||
ty::struct(tcx, oper_t) == ty::ty_bool) {
|
ty::struct(tcx, oper_t) == ty::ty_bool) {
|
||||||
oper_t = check_user_unop(fcx, "!", "op_not", expr, oper_t);
|
oper_t = check_user_unop(fcx, "!", "!", expr, oper_t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::neg {
|
ast::neg {
|
||||||
oper_t = structurally_resolved_type(fcx, oper.span, oper_t);
|
oper_t = structurally_resolved_type(fcx, oper.span, oper_t);
|
||||||
if !(ty::type_is_integral(tcx, oper_t) ||
|
if !(ty::type_is_integral(tcx, oper_t) ||
|
||||||
ty::type_is_fp(tcx, oper_t)) {
|
ty::type_is_fp(tcx, oper_t)) {
|
||||||
oper_t = check_user_unop(fcx, "-", "op_neg", expr, oper_t);
|
oper_t = check_user_unop(fcx, "-", "neg", expr, oper_t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2337,7 +2329,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
||||||
_ {
|
_ {
|
||||||
let resolved = structurally_resolved_type(fcx, expr.span,
|
let resolved = structurally_resolved_type(fcx, expr.span,
|
||||||
raw_base_t);
|
raw_base_t);
|
||||||
alt lookup_op_method(fcx, expr, resolved, "op_index",
|
alt lookup_op_method(fcx, expr, resolved, "[]",
|
||||||
[some(idx)]) {
|
[some(idx)]) {
|
||||||
some(ret_ty) { write::ty_only_fixup(fcx, id, ret_ty); }
|
some(ret_ty) { write::ty_only_fixup(fcx, id, ret_ty); }
|
||||||
_ {
|
_ {
|
||||||
|
|
|
@ -284,7 +284,7 @@ fn parse_ty_methods(p: parser) -> [ast::ty_method] {
|
||||||
parse_seq(token::LBRACE, token::RBRACE, seq_sep_none(), {|p|
|
parse_seq(token::LBRACE, token::RBRACE, seq_sep_none(), {|p|
|
||||||
let flo = p.span.lo;
|
let flo = p.span.lo;
|
||||||
expect_word(p, "fn");
|
expect_word(p, "fn");
|
||||||
let ident = parse_value_ident(p);
|
let ident = parse_method_name(p);
|
||||||
let tps = parse_ty_params(p);
|
let tps = parse_ty_params(p);
|
||||||
let f = parse_ty_fn(ast::proto_bare, p), fhi = p.last_span.hi;
|
let f = parse_ty_fn(ast::proto_bare, p), fhi = p.last_span.hi;
|
||||||
expect(p, token::SEMI);
|
expect(p, token::SEMI);
|
||||||
|
@ -1824,10 +1824,19 @@ fn parse_item_fn(p: parser, purity: ast::purity,
|
||||||
ast::item_fn(decl, t.tps, body), attrs);
|
ast::item_fn(decl, t.tps, body), attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_method_name(p: parser) -> ast::ident {
|
||||||
|
alt p.token {
|
||||||
|
token::BINOP(op) { p.bump(); token::binop_to_str(op) }
|
||||||
|
token::NOT { p.bump(); "!" }
|
||||||
|
token::LBRACKET { p.bump(); expect(p, token::RBRACKET); "[]" }
|
||||||
|
_ { parse_value_ident(p) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_method(p: parser) -> @ast::method {
|
fn parse_method(p: parser) -> @ast::method {
|
||||||
let lo = p.span.lo;
|
let lo = p.span.lo;
|
||||||
expect_word(p, "fn");
|
expect_word(p, "fn");
|
||||||
let ident = parse_value_ident(p);
|
let ident = parse_method_name(p);
|
||||||
let tps = parse_ty_params(p);
|
let tps = parse_ty_params(p);
|
||||||
let decl = parse_fn_decl(p, ast::impure_fn);
|
let decl = parse_fn_decl(p, ast::impure_fn);
|
||||||
let body = parse_block(p);
|
let body = parse_block(p);
|
||||||
|
|
|
@ -1,20 +1,24 @@
|
||||||
type point = {x: int, y: int};
|
type point = {x: int, y: int};
|
||||||
|
|
||||||
impl add_point for point {
|
impl point_ops for point {
|
||||||
fn op_add(other: point) -> point {
|
fn +(other: point) -> point {
|
||||||
{x: self.x + other.x, y: self.y + other.y}
|
{x: self.x + other.x, y: self.y + other.y}
|
||||||
}
|
}
|
||||||
fn op_neg() -> point {
|
fn -(other: point) -> point {
|
||||||
|
{x: self.x - other.x, y: self.y - other.y}
|
||||||
|
}
|
||||||
|
fn neg() -> point {
|
||||||
{x: -self.x, y: -self.y}
|
{x: -self.x, y: -self.y}
|
||||||
}
|
}
|
||||||
fn op_index(x: bool) -> int {
|
fn [](x: bool) -> int {
|
||||||
x ? self.x : self.y
|
x ? self.x : self.y
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let p = {x: 10, y: 20};
|
let p = {x: 10, y: 20};
|
||||||
p += {x: 1, y: 2};
|
p += {x: 101, y: 102};
|
||||||
|
p -= {x: 100, y: 100};
|
||||||
assert p + {x: 5, y: 5} == {x: 16, y: 27};
|
assert p + {x: 5, y: 5} == {x: 16, y: 27};
|
||||||
assert -p == {x: -11, y: -22};
|
assert -p == {x: -11, y: -22};
|
||||||
assert p[true] == 11;
|
assert p[true] == 11;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue