📄 eval.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, "ceiling", "if" and "+" * * \param count to count the number of operand * \param operand to point the first operand or the result after recursion * \param operand2 to point the second operand * \param operand3 to point the third operand * \param cur to point the cdr of c * \param result to store the result after calculation * \param checkint to check if the result is an integer * * \return the operand after evaluation */ 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))) //check whether operand exist errorfct(1); if (nullp(car(cdr(c)))) //check whether operand exist errorfct(2); //check whether operand exist Cell *operand = car(cdr(c)); // first operand Cell *cur = cdr(c); while (cur != NULL) // count the number of operand { count++; cur = cdr(cur); } if (count != 1) // check whether the number of operand is suitable errorfct(3); else if (listp(operand)) //the operand is a function list { Cell *temp = eval(operand); //recursion if (!doublep(temp)) //check whether the type of operand is suitable errorfct(4); Cell *result = make_int(ceil(get_double(temp))); //ceiling the operand return result; } else if (!listp(operand)) //the operand not a function list { if (!doublep(operand)) //check whether the type of operand is suitable errorfct(4); Cell *result = make_int(ceil(get_double(operand))); //ceiling the operand return result; } } // for operator "if" if (get_symbol(car(c)) == "if") { if (nullp(cdr(c))) //check whether operand exist errorfct(1); if (nullp(car(cdr(c)))) //check whether operand exist errorfct(2); Cell *cur = cdr(c); while (cur != NULL) // count the number of operand { count++; cur = cdr(cur); } if (count < 2 || count > 3) // check whether the number of operand is suitable errorfct(3); cur = cdr(c); Cell *operand = car(cur); // first operand if (listp(operand)) //the operand is a function list operand = eval(operand); if (doublep(operand) && get_double(operand) == 0.0) // check wheather the first operand is zero { if (count != 3) // check whether the number of operand is suitable errorfct(3); else { Cell *operand3 = car(cdr(cdr(cur))); //third operand if (listp(operand3)) operand3 = eval(operand3); return operand3; } } else if (intp(operand) && get_int(operand) == 0) // check wheather the first operand is zero { if (count != 3) // check whether the number of operand is suitable errorfct(3); else { Cell *operand3 = car(cdr(cdr(cur))); //third operand if (listp(operand3)) operand3 = eval(operand3); return operand3; } } else { Cell *operand2 = car(cdr(cur)); // second operand if (listp(operand2)) operand2 = eval(operand2); return operand2; } } // for operator "+" if (get_symbol(car(c)) == "+") { if (nullp(cdr(c))) //check whether operand exist and initialize it return make_int(0); if (nullp(car(cdr(c)))) //check whether operand exist errorfct(2); Cell *operand = car(cdr(c)); // first operand Cell *cur = cdr(c); double result = 0.0; // initialize the result int checkint = 0; // check the result either double or integer while (true) { if (listp(operand)) //the operand is a function list operand = eval(operand); //recursion if (symbolp(operand)) //check whether the type of operand is suitable errorfct(4); if (intp(operand)) //check the type and calculate result += get_int(operand); else if (doublep(operand)) { checkint = 1; result += get_double(operand); } if (cdr(cur) == NULL) break; cur = cdr(cur); operand = car(cur); } if (checkint != 0) return make_double(result); else return make_int(result); } else errorfct(5);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -