/*
* This is a stack of Expression_Part shared pointers. It is used to evaluate
* expressions. The stack is based on the standard list type.
*/
#ifndef _EXPR_STACK_H_
#define _EXPR_STACK_H_
#include <memory>
using std::shared_ptr;
#include <list>
using std::list;
#include "expression_parts.h"
class expr_stack: public list<shared_ptr<Expression_Part>>
{
public:
// Stack push.
void push(shared_ptr<Expression_Part> e) { push_front(e); }
// Stack top operation, throws if the stack is empty.
shared_ptr<Expression_Part> top() {
if(empty()) throw bad_expression("Stack underflow: Missing "
"operator or unbalanced parens");
return front();
}
// Stack pop, uses top() so it throws if the stack is empty.
shared_ptr<Expression_Part> pop()
{
auto ret = top();
pop_front();
return ret;
}
// Apply the pop operand, operator, operand off the stack and apply
// them, until reaching a left paren or higher precedence operator.
// Throws if something goes wrong.
void reduce(int prec_limit = -1) { while(merge_top(prec_limit)); }
private:
// Replaces
// operand1 operator operand2 .... |--
// With
// operator(operand2, operand1) .... |--
// If the the top of the stack looks like that. Return success if this
// happens. If the top is of a different, but legal form, returns
// false and does nothing. Otherwise, throws. Also doesn't merge (and
// returns false) if the operator has lower precedence than the
// argument prec_limit.
bool merge_top(int prec_limit = -1);
};
#endif