Exemplo n.º 1
0
Result Calculator::run(Expression expr)
{
    auto rpn = _parser.toRPN(expr);
    RPNStack calcStack;

    while (!rpn.empty()) {
        auto element = rpn.top();
        if (!_parser.isOperator(element)) {
            calcStack.push(element);
            rpn.pop();
            continue;
        }
        auto rhs = BigInteger(calcStack.top());
        calcStack.pop();
        auto lhs = BigInteger(calcStack.top());
        calcStack.pop();

        BigInteger result;

        if (element == "*") {
            result = lhs * rhs;
        } else if (element == "+") {
            result = lhs + rhs;
        } else if (element == "-") {
            result = lhs - rhs;
        }

        calcStack.push(result.value());
        rpn.pop();
    }

    return calcStack.top();
}
Exemplo n.º 2
0
void RPNFunction::evaluate(RPNScript & scr, RPNStack & st) const
{
	RPNConst * res = evaluateFun(st);
	if (res != 0)
		st.push(res);
	scr.nextCmd();
}
Exemplo n.º 3
0
void RPNGo::evaluate(RPNScript & scr, RPNStack & st) const
{
	RPNElem * op = st.pop();
	RPNLabel * label = dynamic_cast<RPNLabel *>(op);

	if (label == 0)
		throw RPNError("Operand is not label");
	scr.goToCmd(label->get());
	delete op;
}
Exemplo n.º 4
0
void RPNGoFalse::evaluate(RPNScript & scr, RPNStack & st) const
{
	RPNConst * opl = st.pop();
	RPNConst * ope = st.pop();
	RPNLabel * label = dynamic_cast<RPNLabel *>(opl);
	RPNInt * exp = dynamic_cast<RPNInt *>(ope);

	if (exp == 0)
		throw RPNError("Operand 1 is not integer");
	if (label == 0)
		throw RPNError("Operand 2 is not label");


	if (exp->get() == 0)
		scr.goToCmd(label->get());
	else
		scr.nextCmd();

	delete opl;
	delete ope;
}
Exemplo n.º 5
0
void TokenListToRPN(TokenList &a_list, RPNStack &a_rpn)
{
	// Shunting yard algorithm
	std::vector<Token*> opStack;
	Token *c_token = a_list.head;

	while (c_token)
	{
		switch (c_token->type)
		{
		case Token::Type::Name:
			if (isalllower(c_token->name, true) && isvalidname(c_token->name))
			{
				if (G::functions.Exists(c_token->name))
				{
					opStack.push_back(c_token);
					c_token->type = Token::Type::E_Function;
				}
				else if (G::variables.Exists(c_token->name))
				{
					a_rpn.push_back({ ExprNode::Type::Number, G::variables.Get(c_token->name) });
				}
				else throw ExpressionError("Undefined reference", c_token);
			}
			else if (isallupper(c_token->name, true) && isvalidname(c_token->name))
			{
				if (G::constants.Exists(c_token->name))
					a_rpn.push_back({ ExprNode::Type::Number, G::constants.Get(c_token->name) });
				else throw ExpressionError("Undefined constant", c_token);
			}
			else throw ExpressionError("Invalid value name", c_token);
			break;
		case Token::Type::Number:
			a_rpn.push_back({ ExprNode::Type::Number, c_token->value });
			break;
		case Token::Type::Operator:
			if (opStack.size() > 0)
			{
				if (c_token->optype == Token::OpType::RPar)
				{
					Token *tos = opStack.back();
					if (opStack.size() == 0)
						throw ExpressionError("#1 Mismatched parenthesis", c_token);
					while (tos->optype != Token::OpType::LPar)
					{
						a_rpn.push_back({ ExprNode::Type::Operator, 0, tos->optype });
						opStack.pop_back();
						tos = opStack.back();
						if (opStack.size() == 0)
							throw ExpressionError("#2 Mismatched parenthesis", c_token);
					}
					opStack.pop_back(); // pop opening parantheses
					if (opStack.size() > 0)
					{
						tos = opStack.back();
						if (tos->type == Token::Type::E_Function)
						{
							a_rpn.push_back({ ExprNode::Type::Function, 0, Token::OpType::None,
								HashFunc(tos->name) });
							opStack.pop_back();
						}
					}
				}
				else if (c_token->optype == Token::OpType::Comma)
				{
					Token *tos = opStack.back();
					if (opStack.size() == 0)
						throw ExpressionError("Invalid separator", c_token);
					while (tos->optype != Token::OpType::LPar)
					{
						a_rpn.push_back({ ExprNode::Type::Operator, 0, tos->optype });
						opStack.pop_back();
						tos = opStack.back();
						if (opStack.size() == 0)
							throw ExpressionError("Invalid separator", c_token);
					}
				}
				else
				{
					if (c_token->optype != Token::OpType::LPar)
					{
						while (opStack.size() > 0 && opStack.back()->optype != Token::OpType::LPar)
						{
							Token *tos = opStack.back();
							if ((is_la(c_token->optype) && precedence(c_token->optype) <= precedence(tos->optype)) ||
								(is_ra(c_token->optype) && precedence(c_token->optype) < precedence(tos->optype)))
							{
								opStack.pop_back();
								a_rpn.push_back({ ExprNode::Type::Operator, 0, tos->optype });
							}
							else break;
						}
					}
					opStack.push_back(c_token);
				}
			}
			else if (c_token->optype != Token::OpType::RPar ||
					c_token->optype != Token::OpType::Comma)
				opStack.push_back(c_token);
			break;
		case Token::Type::Special:
			a_rpn.push_back({ ExprNode::Type::Special, 0, ExprNode::OpType::None, 0, c_token->sptype });
			break;
		}

		c_token = c_token->next;
	}
	
	for (unsigned i = opStack.size(); i-- > 0; )
	{
		if (opStack[i]->optype == Token::OpType::LPar ||
			opStack[i]->optype == Token::OpType::RPar)
			throw ExpressionError("#3 Mismatched parenthesis", opStack[i]);
		a_rpn.push_back({ ExprNode::Type::Operator, 0, opStack[i]->optype });
	}
}
Exemplo n.º 6
0
void RPNConst::evaluate(RPNScript & scr, RPNStack & st) const
{
	st.push(clone());
	scr.nextCmd();
}