Fixed the Wii port so that it compiles.
[rpn.git] / src / Calculator.cpp
blob6434b93736bc2ea9e70c42264d45e09d36a07040
1 /*******************************************************************************
2 * Reverse Polish Notation calculator. *
3 * Copyright (c) 2007-2008, Samuel Fredrickson <kinghajj@gmail.com> *
4 * All rights reserved. *
5 * *
6 * Redistribution and use in source and binary forms, with or without *
7 * modification, are permitted provided that the following conditions are met: *
8 * * Redistributions of source code must retain the above copyright *
9 * notice, this list of conditions and the following disclaimer. *
10 * * Redistributions in binary form must reproduce the above copyright *
11 * notice, this list of conditions and the following disclaimer in the *
12 * documentation and/or other materials provided with the distribution. *
13 * *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS *
15 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED *
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
17 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY *
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR *
20 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *
21 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY *
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
24 * DAMAGE. *
25 ******************************************************************************/
27 /*******************************************************************************
28 * Calculator.cpp - non-command Calculator methods. *
29 ******************************************************************************/
31 #include "rpn.h"
32 #include <boost/tokenizer.hpp>
33 #include <sstream>
34 using namespace boost;
35 using namespace std;
36 using namespace RPN;
38 void Calculator::Eval(string s)
40 typedef tokenizer< char_separator<char> > Tokens;
41 char_separator<char> sep(" \t\n");
42 Tokens tokens(s, sep);
44 if(!HasStack()) return;
46 for(Tokens::iterator tok = tokens.begin();
47 tok != tokens.end() && status == Continue;
48 ++tok)
50 Commands::iterator foundCommand = commands.find(*tok);
51 Operators::iterator foundOperator = operators.find(*tok);
52 Variables::iterator foundVariable = variables.find(*tok);
53 Value val;
55 // if the token is a number, push it.
56 if(istringstream(*tok) >> val)
57 CurrentStack().push_front(val);
59 // if the token is a command, perform it.
60 else if(foundCommand != commands.end())
62 const Command& command = foundCommand->second;
63 vector<string> args;
64 args.reserve(command.NumArgs());
66 // collect a list of tokens that will be the arguments to the
67 // command.
68 while(tok != tokens.end() && args.size() != command.NumArgs())
69 args.push_back(*++tok);
71 // only perform a command if we can give it enough arguments.
72 if(args.size() == command.NumArgs())
73 command.Perform(*this, args);
76 // if the token is an operator and that stack has at least two items,
77 // then perform that operator.
78 else if(foundOperator != operators.end() && StackSize() > 1)
80 Value b = TopmostItem(); CurrentStack().pop_front();
81 Value a = TopmostItem(); CurrentStack().pop_front();
82 CurrentStack().push_front(foundOperator->second(a, b));
85 // if the token is a variable, push the variable onto the stack.
86 else if(foundVariable != variables.end())
87 CurrentStack().push_front(foundVariable->second);
89 // otherwise, if the stack has at least one item, set a new variable
90 // whose name is the token and value is the top item.
91 else variables[*tok] = TopmostItem();
95 // displays the top item of the stack if there is one.
96 // I tried to write this as a friend operator<<(), but I got errors for
97 // accessing private data, which is what friend functions are supposed to be
98 // able to do!
99 void Calculator::Display() const
101 Print(TopmostItem());