I'm not sure I'd go with the operator overloading here. It does mean you have to keep a firm grasp on all the interfaces and remember what a variable is supposed to contain. It also makes spotting mistakes harder - if I have the wrong object in $current_token, $current_token->equals($token) may well have Perl complaining it can't find that method, while $current_token == $token will (more or less) quietly do the wrong thing.
I like overloading, but I believe it is very, very dangerous if used too readily. It's great when you're creating a class that shares characteristics with the basic data types, like writing a Math::Complex or something, where $a * $b ends up meaning exactly what I expect. Also, overloading stringification is very handy. I would be really hesitant to use it to represent more arbitrary semantics.
As for your example, I'd probably want something like this:
my $point = new Point(42, 42); my $start_point = $point->copy; $point->add_x(1) while $image->element_at($point)->color == RED; my $end_point = $point->copy; $image->draw_line($start_point, $end_point, BLACK);
Makeshifts last the longest.