int Eval() { switch (type) { case Terminal: return value; case Unary: { int z = lhs->Eval(); switch (index) { case 0: return factorial(z); break; case 1: return doubleFactorial(z); break; case 2: return subFactorial(z); break; case 3: // square root. really nasty if (z < 0) return numeric_limits<int>::quiet_NaN(); // fail else { float r = sqrtf((float)z); if (r == floor(r)) return (int)r; else return numeric_limits<int>::quiet_NaN(); } } } case Binary: assert(lhs); assert(rhs); return binaryFunctions[index](lhs->Eval(), rhs->Eval()); default: assert(!"Should not be here!"); } }
void Simplify() { if (type == Unary) { lhs->Simplify(); auto z = lhs->Eval(); if ((z >= 0 && z <= 5) || z == 48 || z == 720) { type = Terminal; value = z; delete lhs; lhs = nullptr; } } else if (type == Binary) { lhs->Simplify(); rhs->Simplify(); auto u = lhs->Eval(); if (u >= 0 && u <= 5) { type = Terminal; value = u; delete lhs; lhs = nullptr; } auto v = rhs->Eval(); if (v >= 0 && v <= 5) { type = Terminal; value = v; delete rhs; rhs = nullptr; } } }
int main(int argc, char* argv[]) { if (argc < 2) { puts("filename missing."); return 1; } FILE* file = fopen(argv[1], "r"); if (file == NULL) { fprintf(stderr, "couldn't open: %s\n", argv[1]); return 1; } yyin = file; Node* root = NULL; yyparse(root); // after calling yyparse, the program has been successfully // parsed and the root of AST is stored in Node* root. Environment global; (root->Eval(&global)); fclose(file); return 0; }