#include #include #include "token.h" #include "node.h" #include "hashtable.h" #include "lexan.h" #include "world.h" int world::evaluate(node * n) { node_type t = n->gettype(); if (t == terror) { cerr << "Error! " << n->getstring() << "\n"; return 0; } else if (t == tnumber) return n->getvalue(); else if (t == tvariable) { int * p = mem.find(n->getstring()); if (p == NULL) { cerr << "Error! undefined variable " << n->getstring() << "\n"; longjmp(error_go, 254); } return * p; } else if (t == toperator) { int L = evaluate(n->getlink(0)); int R = evaluate(n->getlink(1)); char c = n->getstring()[0]; switch (c) { case '+': return L + R; case '-': return L - R; case '*': return L * R; case '/': { if (R == 0) { cout << "division by zero!\n"; longjmp(error_go, 234); } return L / R; } case '^': return power(L, R); default: { cout << "error operator '" << c << "'\n"; return 0; } } } else { cerr << "Error evaluate node type " << n->gettype() << "\n"; return 0; } } int world::main_evaluate(node * n) { int a = setjmp(error_go); if (a != 0) return 0; return evaluate(n); } void world::setvar(string name, int value) { mem.set(name, value); } int world::power(int a, int b) { if (b == 0) { if (a == 0) { cout << "Error! 0^0\n"; longjmp(error_go, 241); } return 1; } if (b < 0) { if (a == 0) { cout << "Error! 0^negative\n"; longjmp(error_go, 242); } if (a == 1) return 1; if (a == -1) { if (b & 1) return -1; return 1; } return 0; } int p = 1; int m = a; while (b > 0) { if (b & 1) p *= m; m *= m; b >>= 1; } return p; }