?? 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
*/
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 + -