⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eval.cpp

📁 building parser with C++ functions
💻 CPP
字号:
/**
 * \file eval.cpp
 *
 * A dummy implementation for example purposes.  Just barely enough is
 * implemented to allow the parser to run.  Merely returns the input
 * expression without evaluating it.
 */

#include "eval.hpp"
#include "math.h"


/**
   * \brief Show different error message
   */
void errorfct(int i = 0)
{

	if (i == 1)
		cerr<< "ERROR: missing operand"<< endl;
	else if (i == 2)
		cerr<< "ERROR: missing operator"<< endl;
	else if (i == 3)
		cerr<< "ERROR: too many operands or too few operands"<< endl;
	else if (i == 4)
		cerr<< "ERROR: wrong type of operand"<< endl;
	else if (i == 5)
		cerr<< "ERROR: not an operator"<< endl;
	else cerr<< "ERROR"<< endl;
	exit(1);
}

/**
   * \brief Do evaluation for different operator
   */

Cell* eval(Cell* const c)
{
	int count = 0;

	// for empty list
	if (nullp(c))
		errorfct(2);

	// for input single operand, i.e 8
	if (!listp(c))
		return c;

	// for no function or no operator
	if (nullp(car(c)))
		errorfct(2);

	// for wrong operator
	if (!symbolp(car(c)))
		errorfct(5);

	// for operator "ceiling"
	if (get_symbol(car(c))=="ceiling")
	{
		if ((nullp(cdr(c))) || (nullp(car(cdr(c)))) || (!nullp(cdr(cdr(c)))))		//check error
			errorfct();

		Cell *operand = car(cdr(c));
		operand = eval(operand);
		return operand->cell_ceil();
	}


	// for operator "floor"
	if (get_symbol(car(c))=="floor")
	{
		if ((nullp(cdr(c))) || (nullp(car(cdr(c)))) || (!nullp(cdr(cdr(c)))))		//check error
			errorfct();

		Cell *operand = car(cdr(c));
		operand = eval(operand);
		return operand->cell_floor();
	}

	// for operator "if"
	if (get_symbol(car(c)) == "if")
	{
		if ((nullp(cdr(c))) || (nullp(car(cdr(c)))))		//check error
			errorfct();

		Cell *cur = cdr(c);
		Cell *operand = car(cdr(c));

		while (cur != NULL)		//check number of operands
		{
			count++;
			cur = cdr(cur);
		}
		if (count < 2 || count > 3)
			errorfct(3);

		operand = eval(operand);

		if ((nullp(operand)) || (!(operand->is_zero())))		// check if the first operand is zero
		{
			Cell *operand2 = car(cdr(cdr(c)));		// return the second operand
			operand2 = eval(operand2);
			return operand2;
		}
		else
		{
			if (count != 3)
				errorfct(3);
			else
			{
				Cell *operand3 = car(cdr(cdr(cdr(c))));		// return the third operand
				operand3 = eval(operand3);
				return operand3;
			}
		}
	}

	// for operator "+"
	if (get_symbol(car(c)) == "+")
	{
		if (nullp(cdr(c)))		// no operand
			return make_int(0);
		if (nullp(car(cdr(c))))		// check error
			errorfct(2);

		Cell *operand = car(cdr(c));
		Cell *cur = cdr(c);
		double result = 0.0;
		int checkint = 0;

		while (true)
		{
			operand = eval(operand);
			if (nullp(operand))
				errorfct(2);
			operand->cell_sum(checkint, result);

			if (cdr(cur) == NULL)
				break;

			cur = cdr(cur);
			operand = car(cur);
		}

		if (checkint != 0)		// return the result for different type
			return make_double(result);
		else return make_int(int(result));
	}

	// for operator "*"
	if (get_symbol(car(c)) == "*")
	{
		if (nullp(cdr(c)))		// no operand
			return make_int(1);
		if (nullp(car(cdr(c))))		// check error
			errorfct(2);

		Cell *operand = car(cdr(c));
		Cell *cur = cdr(c);
		double result = 1.0;
		int checkint = 0;

		while (true)
		{
			operand = eval(operand);
			if (nullp(operand))
				errorfct(2);
			operand->cell_times(checkint, result);

			if (cdr(cur) == NULL)
				break;

			cur = cdr(cur);
			operand = car(cur);
		}

		if (checkint != 0)		// return the result for different type
			return make_double(result);
		else return make_int(int(result));
	}

	// for operator "-"
	if (get_symbol(car(c)) == "-")
	{
		if ((nullp(cdr(c))) || (nullp(car(cdr(c)))))		// check error
 		{
			cerr<< "ERROR: zero argument"<< endl;
			exit(1);
		}

		Cell *operand = car(cdr(c));
		Cell *cur = cdr(c);
		double result = 0.0;
		int checkint = 0;

		if (!nullp(cdr(cdr(c))))		// put the first operand into result
		{
			operand = eval(operand);
			if (nullp(operand))
				errorfct(2);
			operand->cell_sum(checkint, result);
			cur = cdr(cur);
			operand = car(cur);
		}

		while (true)
		{
			operand = eval(operand);
			if (nullp(operand))
				errorfct(2);
			operand->cell_sub(checkint, result);

			if (cdr(cur) == NULL)
				break;

			cur = cdr(cur);
			operand = car(cur);
		}

		if (checkint != 0)		// return the result for different type
			return make_double(result);
		else return make_int(int(result));
	}

	// for operator "/"
	if (get_symbol(car(c)) == "/")
	{

		if ((nullp(cdr(c))) || (nullp(car(cdr(c)))))		// check error
 		{
			cerr<< "ERROR: zero argument"<< endl;
			exit(1);
		}

		Cell *operand = car(cdr(c));
		Cell *cur = cdr(c);
		double result = 1.0;
		int checkint = 0;

		if (!nullp(cdr(cdr(c))))		// put the first operand into result
		{
			operand = eval(operand);
			if (nullp(operand))
				errorfct(2);
			operand->cell_times(checkint, result);
			cur = cdr(cur);
			operand = car(cur);
		}

		while (true)
		{
			operand = eval(operand);
			if (nullp(operand))
				errorfct(2);
			operand->cell_div(checkint, result);

			if (cdr(cur) == NULL)
				break;

			cur = cdr(cur);
			operand = car(cur);
		}

		if (checkint == 0)		// return the result for different type
			return make_int(int(result));
		else return make_double(result);
	}

	// for operator "quote"
	if (get_symbol(car(c)) == "quote")
	{
		if ((nullp(cdr(c))) || (!nullp(cdr(cdr(c)))))		// check error
			errorfct();
		return car(cdr(c));
	}

	// for operand "cons"
	if (get_symbol(car(c)) == "cons")
	{
		if ((nullp(cdr(c))) || (nullp(car(cdr(c)))) || (nullp(cdr(cdr(c)))) || (!nullp(cdr(cdr(cdr(c))))))		// check error
			errorfct();
		Cell *operand = car(cdr(c));
		Cell *operand2 = car(cdr(cdr(c)));
		if (!operand2->is_list())
			errorfct();
		return new ConsCell (eval(operand), eval(operand2));
	}

	// for operator "car"
	if (get_symbol(car(c)) == "car")
	{
		if ((nullp(cdr(c))) || (nullp(car(cdr(c)))) || (!nullp(cdr(cdr(c)))))		// check error
			errorfct();
		Cell *operand = car(cdr(c));
		return car(eval(operand));
	}

	// for operator "cdr"
	if (get_symbol(car(c)) == "cdr")
	{
		if ((nullp(cdr(c))) || (nullp(car(cdr(c)))) || (!nullp(cdr(cdr(c)))))		// check error
			errorfct();
		Cell *operand = car(cdr(c));
		return cdr(eval(operand));
	}

	// for operator "nullp"
	if (get_symbol(car(c)) == "nullp")
	{
		if ((nullp(cdr(c))) || (nullp(car(cdr(c)))) || (!nullp(cdr(cdr(c)))))		// check error
			errorfct();
		Cell *operand = car(cdr(c));
		operand = eval(operand);
		if (nullp(operand))		// check null
			return make_int(1);
		else
			return make_int(0);
	}
	errorfct(5);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -