Perl Quiz of the Week #25 (RPN calculator)

demerphq <[email protected]> Wed, 29 Sep 2004 16:09:33 +0200
Newsgroups gmane.comp.lang.perl.qotw.discuss
Message-ID <[email protected]>
On Wed, 29 Sep 2004 12:00:08 GMT, Smylers <smylers-/[email protected]> wrote:
> demerphq writes:
>
> > Is minus considered to be a binary operator or a unary operator or
> > both?
>
> I can't be both, cos with postfix notation that's ambiguous.
> Conventionally it's a binary operator.

Ok, thats what I assumed you would say. :-)

> > Ie: is -1 a legal value for the system
>
> I suppose that even with "-" as a binary operator you could still treat
> "-1" as being a negative number.  That then means that "-1" is different
> from "- 1", in the same way that "3 4" is different from "34".

Well, the key thing here is that the tokenizing rules you stated
involved splitting on whitespace so having -1 be treated as - 1 would
appear to break that edict.

>
> The Unix command dc (a RPN calculator similar to the one in this quiz)
> uses underscore for negative numbers.  But this is a way of _denoting_ a
> single negative number, such as "_1" for -1; it is _not_ a unary minus
> operator, which would of course follow the number it is making negative.
>
> You could use a symbol for unary minus, so long as it is distinct from
> binary minus (and also from denoting a negative number, if you have such
> a symbol).
>
> But such an operator isn't necessary: if you have some way of denoting
> negative numbers then you can make do with "-1 *" (or "_1*" or whatever)
> instead.
>
> Or if you don't even have that then you can still perform unary minus
> with "0 swap -".

Cool. Thanks a lot.

Also I thought i'd mention something i came up with:

I added a special rule that says that if an input line matches
/^\s*:\s*/ then everything after the :\s* is treated a literal and
pushed onto the stack.

This combined with a "load" command allows new operators to be defined
in perl on the fly, likewise, a 'def' command allows new RPN token
sequences to be evaluated as a function.

In more detail 'def' pops a name from the stack, then pops a RPN
string from the stack and sets it up as a function. It returns 0 if
there is an error and 1 if the definition was successful.

'load' works similarly but has calling details which are
implementation specific so i won't mention them.

Eg:

> : + 2 /
0: + 2 /
> avg_of_2 def
0: 1
> clear
> 1 2 avg_of_2
0: 1.5
> : avg_of_2 avg_of_2
1: avg_of_2 avg_of_2
0: 1.5
> combined def
1: 1
0: 1.5
> 1
2: 1
1: 1
0: 1.5
> combined
0: 1.25
>

Anyway, thanks for the Quiz, its proved quite interesting to hack on.
I look forward to posting my solution once the quiet period is over.

cheers
ps(Forgot the list on my original posting, so this is a resend.)
--
First they ignore you, then they laugh at you, then they fight you,
then you win.
 +Gandhi