void ui() { Evaluator eval; std::string input; std::cout << "\ntype an expression, \"exit\" to end\n"; while (true) { std::cout << ">>> "; std::getline(std::cin, input); if (input[0] == 'e' || input[0] == 'E') break; try { std::cout << eval.eval(input) << std::endl; } catch (std::invalid_argument err) { std::cout << "Error: " << err.what() << std::endl; } } }
int main() { Evaluator eval; vector<string> expression = { "1+2*3","2+2^2*3" ,"1==2", "1+3 > 2", "(4>=4) && 0", "(1+2)*3" }; //<--expressions we wish to evaluate go here vector<string>::iterator exprItr; for (exprItr = expression.begin(); exprItr != expression.end(); exprItr++) { try { int result = eval.eval(*exprItr); cout << eval.infix_expression.c_str() << " = " << result << endl << endl; } catch (Syntax_Error e) { cout << eval.infix_expression.c_str() << endl << e.what() << " " << "@ char: " << eval.position << endl << endl; } } system("pause"); return 0; }
int evaluate(T& src) { Evaluator e; try { e.eval(src); return 0; } catch (const Error& e) { std::cerr << DASHES << std::endl; std::cerr << "Unhandled exception!" << std::endl << std::endl; std::cerr << e.what() << std::endl; std::cerr << DASHES << std::endl; return 1; } }
Expr* get_length(Layout_decl const* layout) { Evaluator eval; Expr* e = 0; for (Decl* d : layout->fields()) { Type const* t1 = d->type(); // If member is constant, just add in the constant value if (has_constant_length(t1)) e = add(e, make_int(precision(t1))); // Otherwise, we have to form a call to the function // that would compute this type. else { // FIXME: Do this right! throw std::runtime_error("unimplemented dynamic length calc."); e = add(e, zero()); } } // Compute ceil(e / 8). Expr* b = make_int(8); // bits per byte Expr* r = div(sub(add(e, b), one()), b); // Try folding the result. If it works, good. If not, // just return the previously computed expression. // // TODO: Maximally reduce the expression so that we only // add the constant bits to the non-constant bits. Since // addition is associative and commutative, we can // partition the sequence of terms into constants and // non-constants, and then sum the constant parts. try { Value v = eval.eval(r); if (v.is_integer()) return make_int(v.get_integer()); else throw std::runtime_error("failed to synth length"); } catch(...) { return r; } }
Expr* gather(Expr_seq const& subkeys) { // maintain the largest allowable key buffer uint512_t buf = 0; Evaluator ev; // maintain the position to start writing int pos = 0; for (auto subkey : subkeys) { // get the precision of the subkey int prec = precision(subkey->type()); Value const& val = ev.eval(subkey); // FIXME: for now we're only dealing with unsigned integer values assert(val.is_integer()); std::stringstream ss; ss << val.get_integer().decimal_str(); uint512_t i = 0; ss >> i; // shift the integer over by the amount already written i = i << pos; // add the length of the current integer to the pos pos += prec; // log-and the integer into the buffer buf |= i; } char* bytes = new char[pos / 8]; char* key = reinterpret_cast<char*>(&buf); std::copy(key, key + (pos / 8), bytes); Array_value arr { bytes, (size_t) pos / 8 }; Type const* z = get_integer_type(); Expr* n = new Literal_expr(z, arr.len + 1); // Create the array type. Type const* c = get_character_type(); Type const* t = get_array_type(c, n); return new Literal_expr(t, arr); }
// Evaluate the given expression. inline Value evaluate(Expr const* e) { Evaluator ev; return ev.eval(e); }