#include "AST.h" #include namespace calc { Number::Number(double d) : m_val(d) {} double Number::eval(const Variables&, const Functions&) const { return m_val; } Var::Var(std::string name) : m_name(name) {} double Var::eval(const Variables& vars, const Functions&) const { auto v = vars.find(m_name); if (v != vars.end()) return v->second; return 0; } std::string Var::getName() const { return m_name; } Binop::Binop(std::unique_ptr&& left, std::string op, std::unique_ptr&& right) : m_left(std::move(left)), m_right(std::move(right)), m_op(op) {} double Binop::eval(const Variables& vars, const Functions& funs) const { double left = m_left->eval(vars, funs); double right = m_right->eval(vars, funs); if (m_op == "+") return left + right; else if (m_op == "-") return left - right; else if (m_op == "*") return left * right; else if (m_op == "/") return left / right; else if (m_op == "^") return std::pow(left, right); return 0; } Unop::Unop(std::string op, std::unique_ptr&& operand) : m_op(op), m_operand(std::move(operand)) {} double Unop::eval(const Variables& vars, const Functions& funs) const { if (m_op == "-") return -m_operand->eval(vars, funs); return 0; } double FormalParameters::eval(const Variables&, const Functions&) const { return 0; } void FormalParameters::push_back(std::unique_ptr&& arg) { m_args.emplace_back(std::move(arg)); } std::deque>::const_iterator FormalParameters::begin() { return m_args.begin(); } std::deque>::const_iterator FormalParameters::end() { return m_args.end(); } double FunctionArguments::eval(const Variables&, const Functions&) const { return 0; } std::unique_ptr& FunctionArguments::operator[](std::size_t idx) { return m_args[idx]; } void FunctionArguments::push_back(std::unique_ptr&& arg) { m_args.push_back(std::move(arg)); } std::size_t FunctionArguments::size() const { return m_args.size(); } FunctionCall::FunctionCall(std::string name, std::unique_ptr&& arguments) : m_name(name), m_arguments(std::move(arguments)) {} double FunctionCall::eval(const Variables& vars, const Functions& funs) const { auto fp = funs.find(m_name); if (fp == funs.end()) return 0; Function& fun = *dynamic_cast((fp->second.get())); if (m_arguments->size() != fun.getParams().size()) return 0; Variables newVars = vars; std::size_t i = 0; for (const std::string& param : fun.getParams()) { newVars[param] = (*m_arguments)[i]->eval(vars, funs); i++; } return fun.eval(newVars, funs); } Function::Function(std::deque formalParams, std::unique_ptr&& body) : m_formalParams(std::move(formalParams)), m_body(std::move(body)) {} double Function::eval(const Variables& vars, const Functions& funs) const { return m_body->eval(vars, funs); } const std::deque& Function::getParams() const { return m_formalParams; } } /* calc */