Changed from stacks to lists.
[rpn.git] / src / rpn.h
blob7a6f941e17f2875956e5791a3f4bcd860021f4f5
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 * rpn.h - common header for the entire program. *
29 ******************************************************************************/
31 #ifndef _RPN_H_
32 #define _RPN_H_
34 #include <iostream>
35 #include <list>
36 #include <map>
37 #include <stack>
38 #include <string>
40 //! Calls an objects member function via pointer.
41 #define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
43 namespace RPN
45 // version information.
46 const int VERSION_MAJOR = 2;
47 const int VERSION_MINOR = 0;
48 const int VERSION_BUILD = 0;
49 const std::string VERSION_EXTRA = "pre";
51 // forward declarations.
52 class Calculator;
53 class Command;
55 // various typedefs.
56 typedef long double Value;
57 typedef Value (*Operator)(Value a, Value b);
58 typedef std::map<std::string, Command> Commands;
59 typedef std::map<std::string, Operator> Operators;
60 typedef std::map<std::string, Value> Variables;
61 typedef std::list<Value> Stack;
62 typedef std::list<Stack> History;
64 //! Returns a default, empty History stack.
65 History defaultHistory();
66 //! Returns a map of the default operators.
67 Operators defaultOperators();
68 //! Returns a map of the default variables.
69 Variables defaultVariables();
71 //! The main class for the program.
72 class Calculator
74 //! Holds the calculator's status, i.e. whether it's running or not.
75 enum Status
77 Continue,
78 Stop
81 Commands commands;
82 History history;
83 Operators operators;
84 Status status;
85 Variables variables;
87 //! The command to duplicate the top item of the stack.
88 void dup (std::list<std::string>&);
89 //! The command to exit the calculator.
90 void exit (std::list<std::string>&);
91 //! Removes the top stack as long as there will be at least one left.
92 void popHistory (std::list<std::string>&);
93 //! Copies the top stack and pushes it onto the history.
94 void pushHistory (std::list<std::string>&);
95 //! The command to print the history.
96 void printHistory (std::list<std::string>&);
97 //! The command to print the stack.
98 void printStack (std::list<std::string>&);
99 //! Pops the top item, then pushes its square root.
100 void sqrtTop (std::list<std::string>&);
101 //! Swaps the top two items of the stack.
102 void swap (std::list<std::string>&);
103 //! Unsets a previously set variable.
104 void unset (std::list<std::string>&);
106 //! Returns true if there is at least one stack.
107 bool HasStack() const { return history.size() != 0; }
109 //! Returns a reference to the current stack.
110 Stack& CurrentStack() { return history.front(); }
112 //! Returns the current stack's size.
113 size_t StackSize() const
115 return HasStack() ? history.front().size() : 0;
118 //! Returns the topmost item of the current stack.
119 Value TopmostItem() const
121 return HasStack() && StackSize() > 0 ? history.front().front() : 0;
124 public:
125 Calculator()
126 : commands (defaultCommands()),
127 history (defaultHistory()),
128 operators (defaultOperators()),
129 status (Continue),
130 variables (defaultVariables())
134 //! Evaluates a string.
135 void Eval(std::string input);
136 //! Returns true if the calculator is running.
137 bool IsRunning() const { return status == Continue; }
139 //! Returns a map of the default commands.
140 Commands defaultCommands();
142 //! Displays the top item of the stack.
143 std::ostream& Display(std::ostream& os = std::cout) const;
146 typedef void (Calculator::*CommandPtr)(std::list<std::string>&);
148 //! Holds information on a command, such as what its function is and how
149 //! many arguments it takes.
150 class Command
152 CommandPtr command_ptr;
153 unsigned num_args;
155 public:
156 Command(CommandPtr command_ptr = NULL, unsigned int num_args = 0)
157 : command_ptr(command_ptr), num_args(num_args)
161 unsigned NumArgs() const { return num_args; }
163 void Perform(Calculator& calculator, std::list<std::string> args) const
165 if(command_ptr)
166 CALL_MEMBER_FN(calculator, command_ptr)(args);
171 #endif // _RPN_H_