diff --git a/src/MacroExpandModFile.cc b/src/MacroExpandModFile.cc index 8a3fd6091d4e0daba61f31577946521e250a7d84..ea383421e84d580d4f367ea3f4fa56cb53151ba0 100644 --- a/src/MacroExpandModFile.cc +++ b/src/MacroExpandModFile.cc @@ -34,8 +34,8 @@ macroExpandModFile(const string &filename, const string &basename, const istream // Do macro processing stringstream macro_output; macro::Environment env = macro::Environment(); - macro::Driver m(env); - m.parse(filename, basename, modfile, debug, defines, paths, macro_output); + macro::Driver m; + m.parse(filename, basename, modfile, debug, defines, env, paths, macro_output); if (save_macro) { if (save_macro_file.empty()) diff --git a/src/macro/Directives.cc b/src/macro/Directives.cc index e76bf4499589c10e30bb42aa239620bbeb078fb1..51abcedf64e803684c35e0886ddfa11171dab3fb 100644 --- a/src/macro/Directives.cc +++ b/src/macro/Directives.cc @@ -25,11 +25,11 @@ using namespace macro; void -Eval::interpret(ostream &output, vector<filesystem::path> &paths) +Eval::interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) { try { - output << expr->eval()->to_string(); + output << expr->eval(env)->to_string(); } catch (StackTrace &ex) { @@ -43,12 +43,12 @@ Eval::interpret(ostream &output, vector<filesystem::path> &paths) } void -Include::interpret(ostream &output, vector<filesystem::path> &paths) +Include::interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) { using namespace filesystem; try { - StringPtr msp = dynamic_pointer_cast<String>(expr->eval()); + StringPtr msp = dynamic_pointer_cast<String>(expr->eval(env)); if (!msp) throw StackTrace("File name does not evaluate to a string"); path filename = msp->to_string(); @@ -71,11 +71,11 @@ Include::interpret(ostream &output, vector<filesystem::path> &paths) +". The following directories were searched:\n" + errmsg.str(), location)); } } - Driver m(env); + Driver m; // Calling `string()` method on filename and filename.stem() because of bug in // MinGW 8.3.0 that ignores implicit conversion to string from filename::path. // Test if bug exists when version of MinGW is upgraded on Debian runners - m.parse(filename.string(), filename.stem().string(), incfile, false, {}, paths, output); + m.parse(filename.string(), filename.stem().string(), incfile, false, {}, env, paths, output); } catch (StackTrace &ex) { @@ -90,12 +90,12 @@ Include::interpret(ostream &output, vector<filesystem::path> &paths) } void -IncludePath::interpret(ostream &output, vector<filesystem::path> &paths) +IncludePath::interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) { using namespace filesystem; try { - StringPtr msp = dynamic_pointer_cast<String>(expr->eval()); + StringPtr msp = dynamic_pointer_cast<String>(expr->eval(env)); if (!msp) throw StackTrace("File name does not evaluate to a string"); path ip = static_cast<string>(*msp); @@ -117,7 +117,7 @@ IncludePath::interpret(ostream &output, vector<filesystem::path> &paths) } void -Define::interpret(ostream &output, vector<filesystem::path> &paths) +Define::interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) { try { @@ -140,11 +140,11 @@ Define::interpret(ostream &output, vector<filesystem::path> &paths) } void -Echo::interpret(ostream &output, vector<filesystem::path> &paths) +Echo::interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) { try { - cout << "@#echo (" << getLocation() << "): " << expr->eval()->to_string() << endl; + cout << "@#echo (" << getLocation() << "): " << expr->eval(env)->to_string() << endl; } catch (StackTrace &ex) { @@ -159,11 +159,11 @@ Echo::interpret(ostream &output, vector<filesystem::path> &paths) } void -Error::interpret(ostream &output, vector<filesystem::path> &paths) +Error::interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) { try { - throw StackTrace(expr->eval()->to_string()); + throw StackTrace(expr->eval(env)->to_string()); } catch (StackTrace &ex) { @@ -177,7 +177,7 @@ Error::interpret(ostream &output, vector<filesystem::path> &paths) } void -EchoMacroVars::interpret(ostream &output, vector<filesystem::path> &paths) +EchoMacroVars::interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) { if (save) env.print(output, vars, location.begin.line, true); @@ -187,12 +187,12 @@ EchoMacroVars::interpret(ostream &output, vector<filesystem::path> &paths) } void -For::interpret(ostream &output, vector<filesystem::path> &paths) +For::interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) { ArrayPtr ap; try { - ap = dynamic_pointer_cast<Array>(index_vals->eval()); + ap = dynamic_pointer_cast<Array>(index_vals->eval(env)); if (!ap) throw StackTrace("The index must loop through an array"); } @@ -236,14 +236,14 @@ For::interpret(ostream &output, vector<filesystem::path> &paths) statement->printLineInfo(output); printLine = false; } - statement->interpret(output, paths); + statement->interpret(output, env, paths); } } printEndLineInfo(output); } void -If::interpret(ostream &output, vector<filesystem::path> &paths) +If::interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) { bool first_clause = true; for (const auto & [expr, body] : expr_and_body) @@ -257,13 +257,13 @@ If::interpret(ostream &output, vector<filesystem::path> &paths) if ((ifdef && env.isVariableDefined(vp->getName())) || (ifndef && !env.isVariableDefined(vp->getName()))) { - interpretBody(body, output, paths); + interpretBody(body, output, env, paths); break; } } else { - auto tmp = expr->eval(); + auto tmp = expr->eval(env); RealPtr dp = dynamic_pointer_cast<Real>(tmp); BoolPtr bp = dynamic_pointer_cast<Bool>(tmp); if (!bp && !dp) @@ -271,7 +271,7 @@ If::interpret(ostream &output, vector<filesystem::path> &paths) "The condition must evaluate to a boolean or a double", location)); if ((bp && *bp) || (dp && *dp)) { - interpretBody(body, output, paths); + interpretBody(body, output, env, paths); break; } } @@ -289,7 +289,7 @@ If::interpret(ostream &output, vector<filesystem::path> &paths) } void -If::interpretBody(const vector<DirectivePtr> &body, ostream &output, vector<filesystem::path> &paths) +If::interpretBody(const vector<DirectivePtr> &body, ostream &output, Environment &env, vector<filesystem::path> &paths) { bool printLine = true; for (const auto &statement : body) @@ -299,6 +299,6 @@ If::interpretBody(const vector<DirectivePtr> &body, ostream &output, vector<file statement->printLineInfo(output); printLine = false; } - statement->interpret(output, paths); + statement->interpret(output, env, paths); } } diff --git a/src/macro/Directives.hh b/src/macro/Directives.hh index cc7ec6e1293d9ad0a4270a807344de0a110da7b2..426e17f3d5b3b0b48a069225d5a88701a35d5bb0 100644 --- a/src/macro/Directives.hh +++ b/src/macro/Directives.hh @@ -30,10 +30,10 @@ namespace macro { // A Parent class just for clarity public: - Directive(Environment &env_arg, Tokenizer::location location_arg) : - Node(env_arg, move(location_arg)) { } + explicit Directive(Tokenizer::location location_arg) : + Node(move(location_arg)) { } // Directives can be interpreted - virtual void interpret(ostream &output, vector<filesystem::path> &paths) = 0; + virtual void interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) = 0; }; @@ -45,9 +45,9 @@ namespace macro private: const string text; public: - TextNode(string text_arg, Environment &env_arg, Tokenizer::location location_arg) : - Directive(env_arg, move(location_arg)), text{move(text_arg)} { } - inline void interpret(ostream &output, vector<filesystem::path> &paths) override { output << text; } + TextNode(string text_arg, Tokenizer::location location_arg) : + Directive(move(location_arg)), text{move(text_arg)} { } + inline void interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) override { output << text; } }; @@ -59,9 +59,9 @@ namespace macro private: const ExpressionPtr expr; public: - Eval(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) : - Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { } - void interpret(ostream &output, vector<filesystem::path> &paths) override; + Eval(ExpressionPtr expr_arg, Tokenizer::location location_arg) : + Directive(move(location_arg)), expr{move(expr_arg)} { } + void interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) override; }; @@ -70,9 +70,9 @@ namespace macro private: const ExpressionPtr expr; public: - Include(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) : - Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { } - void interpret(ostream &output, vector<filesystem::path> &paths) override; + Include(ExpressionPtr expr_arg, Tokenizer::location location_arg) : + Directive(move(location_arg)), expr{move(expr_arg)} { } + void interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) override; }; @@ -81,9 +81,9 @@ namespace macro private: const ExpressionPtr expr; public: - IncludePath(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) : - Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { } - void interpret(ostream &output, vector<filesystem::path> &paths) override; + IncludePath(ExpressionPtr expr_arg, Tokenizer::location location_arg) : + Directive(move(location_arg)), expr{move(expr_arg)} { } + void interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) override; }; @@ -96,13 +96,13 @@ namespace macro public: Define(VariablePtr var_arg, ExpressionPtr value_arg, - Environment &env_arg, Tokenizer::location location_arg) : - Directive(env_arg, move(location_arg)), var{move(var_arg)}, value{move(value_arg)} { } + Tokenizer::location location_arg) : + Directive(move(location_arg)), var{move(var_arg)}, value{move(value_arg)} { } Define(FunctionPtr func_arg, ExpressionPtr value_arg, - Environment &env_arg, Tokenizer::location location_arg) : - Directive(env_arg, move(location_arg)), func{move(func_arg)}, value{move(value_arg)} { } - void interpret(ostream &output, vector<filesystem::path> &paths) override; + Tokenizer::location location_arg) : + Directive(move(location_arg)), func{move(func_arg)}, value{move(value_arg)} { } + void interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) override; }; @@ -112,9 +112,9 @@ namespace macro const ExpressionPtr expr; public: Echo(ExpressionPtr expr_arg, - Environment &env_arg, Tokenizer::location location_arg) : - Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { } - void interpret(ostream &output, vector<filesystem::path> &paths) override; + Tokenizer::location location_arg) : + Directive(move(location_arg)), expr{move(expr_arg)} { } + void interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) override; }; @@ -124,9 +124,9 @@ namespace macro const ExpressionPtr expr; public: Error(ExpressionPtr expr_arg, - Environment &env_arg, Tokenizer::location location_arg) : - Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { } - void interpret(ostream &output, vector<filesystem::path> &paths) override; + Tokenizer::location location_arg) : + Directive(move(location_arg)), expr{move(expr_arg)} { } + void interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) override; }; @@ -137,12 +137,12 @@ namespace macro const vector<string> vars; public: EchoMacroVars(bool save_arg, - Environment &env_arg, Tokenizer::location location_arg) : - Directive(env_arg, move(location_arg)), save{save_arg} { } + Tokenizer::location location_arg) : + Directive(move(location_arg)), save{save_arg} { } EchoMacroVars(bool save_arg, vector<string> vars_arg, - Environment &env_arg, Tokenizer::location location_arg) : - Directive(env_arg, move(location_arg)), save{save_arg}, vars{move(vars_arg)} { } - void interpret(ostream &output, vector<filesystem::path> &paths) override; + Tokenizer::location location_arg) : + Directive(move(location_arg)), save{save_arg}, vars{move(vars_arg)} { } + void interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) override; }; @@ -156,10 +156,10 @@ namespace macro For(vector<VariablePtr> index_vec_arg, ExpressionPtr index_vals_arg, vector<DirectivePtr> statements_arg, - Environment &env_arg, Tokenizer::location location_arg) : - Directive(env_arg, move(location_arg)), index_vec{move(index_vec_arg)}, + Tokenizer::location location_arg) : + Directive(move(location_arg)), index_vec{move(index_vec_arg)}, index_vals{move(index_vals_arg)}, statements{move(statements_arg)} { } - void interpret(ostream &output, vector<filesystem::path> &paths) override; + void interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) override; }; @@ -178,22 +178,22 @@ namespace macro const bool ifdef, ifndef; public: If(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg, - Environment &env_arg, Tokenizer::location location_arg, + Tokenizer::location location_arg, bool ifdef_arg = false, bool ifndef_arg = false) : - Directive(env_arg, move(location_arg)), expr_and_body{move(expr_and_body_arg)}, + Directive(move(location_arg)), expr_and_body{move(expr_and_body_arg)}, ifdef{ifdef_arg}, ifndef{ifndef_arg} { } - void interpret(ostream &output, vector<filesystem::path> &paths) override; + void interpret(ostream &output, Environment &env, vector<filesystem::path> &paths) override; protected: void interpretBody(const vector<DirectivePtr> &body, ostream &output, - vector<filesystem::path> &paths); + Environment &env, vector<filesystem::path> &paths); }; class Ifdef : public If { public: Ifdef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg, - Environment &env_arg, Tokenizer::location location_arg) : - If(move(expr_and_body_arg), env_arg, move(location_arg), true, false) { } + Tokenizer::location location_arg) : + If(move(expr_and_body_arg), move(location_arg), true, false) { } }; @@ -201,8 +201,8 @@ namespace macro { public: Ifndef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg, - Environment &env_arg, Tokenizer::location location_arg) : - If(move(expr_and_body_arg), env_arg, move(location_arg), false, true) { } + Tokenizer::location location_arg) : + If(move(expr_and_body_arg), move(location_arg), false, true) { } }; } #endif diff --git a/src/macro/Driver.cc b/src/macro/Driver.cc index c05ec35bfafef3d570c91505efd257776b21ece9..6e80a7c403049dd0f6e97cc77d470814e3ded969 100644 --- a/src/macro/Driver.cc +++ b/src/macro/Driver.cc @@ -25,7 +25,7 @@ using namespace macro; void Driver::parse(const string &file_arg, const string &basename_arg, const istream &modfile, bool debug, const vector<pair<string, string>> &defines, - vector<filesystem::path> &paths, ostream &output) + Environment &env, vector<filesystem::path> &paths, ostream &output) { file = file_arg; basename = basename_arg; @@ -35,9 +35,9 @@ Driver::parse(const string &file_arg, const string &basename_arg, const istream stringstream command_line_defines_with_endl; for (const auto & [var, val] : defines) command_line_defines_with_endl << "@#define " << var << " = " << val << endl; - Driver m(env); + Driver m; istream is(command_line_defines_with_endl.rdbuf()); - m.parse("command_line_defines", "command_line_defines", is, debug, {}, paths, output); + m.parse("command_line_defines", "command_line_defines", is, debug, {}, env, paths, output); } // Handle empty files @@ -65,7 +65,7 @@ Driver::parse(const string &file_arg, const string &basename_arg, const istream statement->printLineInfo(output); printLine = false; } - statement->interpret(output, paths); + statement->interpret(output, env, paths); } } diff --git a/src/macro/Driver.hh b/src/macro/Driver.hh index 7bf9765559fa4116702e9489bb25e80271037f95..c6ab34d1109f1da03a2ffc29fef8f5e904a2a6ef 100644 --- a/src/macro/Driver.hh +++ b/src/macro/Driver.hh @@ -61,14 +61,11 @@ namespace macro //! Implements the macro expansion using a Flex scanner and a Bison parser class Driver { - public: - Environment &env; private: vector<DirectivePtr> statements; stack<vector<DirectivePtr>> directive_stack; public: - Driver(Environment &env_arg) : - env{env_arg} { } + Driver() = default; Driver(const Driver &) = delete; Driver(Driver &&) = delete; Driver &operator=(const Driver &) = delete; @@ -84,12 +81,11 @@ namespace macro } }; - //! Starts parsing a file, modifies `paths` and `output` - //! Both `paths` and `output` are passed as reference + //! Starts parsing a file, modifies `env`, `paths` and `output` //! as they are modified by various macro directives void parse(const string &file, const string &basename, const istream &modfile, bool debug, const vector<pair<string, string>> &defines, - vector<filesystem::path> &paths, ostream &output); + Environment &env, vector<filesystem::path> &paths, ostream &output); //! Name of main file being parsed string file; diff --git a/src/macro/Environment.cc b/src/macro/Environment.cc index 25826a5fbb216e978c36c72528f85da8e06b6081..17b6e1bed3880d431f16a64f4f45985b5dae7b9d 100644 --- a/src/macro/Environment.cc +++ b/src/macro/Environment.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2019 Dynare Team + * Copyright © 2019-2020 Dynare Team * * This file is part of Dynare. * @@ -28,7 +28,7 @@ Environment::define(VariablePtr var, ExpressionPtr value) string name = var->getName(); if (functions.count(name)) throw StackTrace("Variable " + name + " was previously defined as a function"); - variables[move(name)] = value->eval(); + variables[move(name)] = value->eval(*this); } void @@ -67,7 +67,7 @@ Environment::getFunction(const string &name) const codes::BaseType Environment::getType(const string &name) const { - return getVariable(name)->eval()->getType(); + return getVariable(name)->eval(const_cast<Environment &>(*this))->getType(); } bool @@ -132,7 +132,7 @@ Environment::printVariable(ostream &output, const string &name, int line, bool s { output << (save ? "options_.macrovars_line_" + to_string(line) + "." : " ") << name << " = "; - getVariable(name)->eval()->print(output, save); + getVariable(name)->eval(const_cast<Environment &>(*this))->print(output, save); if (save) output << ";"; output << endl; diff --git a/src/macro/Expressions.cc b/src/macro/Expressions.cc index a14b380fafd361827ccd58b38718bb8327dbd973..e3fcb5f8f1ce92ce8cda770f103d4070c008ffb7 100644 --- a/src/macro/Expressions.cc +++ b/src/macro/Expressions.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2019 Dynare Team + * Copyright © 2019-2020 Dynare Team * * This file is part of Dynare. * @@ -25,8 +25,8 @@ BoolPtr BaseType::is_different(const BaseTypePtr &btp) const { if (*(this->is_equal(btp))) - return make_shared<Bool>(false, env); - return make_shared<Bool>(true, env); + return make_shared<Bool>(false); + return make_shared<Bool>(true); } BoolPtr @@ -34,38 +34,38 @@ Bool::is_equal(const BaseTypePtr &btp) const { auto btp2 = dynamic_pointer_cast<Bool>(btp); if (!btp2) - return make_shared<Bool>(false, env); - return make_shared<Bool>(value == btp2->value, env); + return make_shared<Bool>(false); + return make_shared<Bool>(value == btp2->value); } BoolPtr -Bool::logical_and(const ExpressionPtr &ep) const +Bool::logical_and(const ExpressionPtr &ep, Environment &env) const { if (!value) - return make_shared<Bool>(false, env); + return make_shared<Bool>(false); - auto btp = ep->eval(); + auto btp = ep->eval(env); if (auto btp2 = dynamic_pointer_cast<Bool>(btp); btp2) - return make_shared<Bool>(*btp2, env); + return make_shared<Bool>(*btp2); if (auto btp2 = dynamic_pointer_cast<Real>(btp); btp2) - return make_shared<Bool>(*btp2, env); + return make_shared<Bool>(*btp2); throw StackTrace("Type mismatch for operands of && operator"); } BoolPtr -Bool::logical_or(const ExpressionPtr &ep) const +Bool::logical_or(const ExpressionPtr &ep, Environment &env) const { if (value) - return make_shared<Bool>(true, env); + return make_shared<Bool>(true); - auto btp = ep->eval(); + auto btp = ep->eval(env); if (auto btp2 = dynamic_pointer_cast<Bool>(btp); btp2) - return make_shared<Bool>(*btp2, env); + return make_shared<Bool>(*btp2); if (auto btp2 = dynamic_pointer_cast<Real>(btp); btp2) - return make_shared<Bool>(*btp2, env); + return make_shared<Bool>(*btp2); throw StackTrace("Type mismatch for operands of || operator"); } @@ -73,7 +73,7 @@ Bool::logical_or(const ExpressionPtr &ep) const BoolPtr Bool::logical_not() const { - return make_shared<Bool>(!value, env); + return make_shared<Bool>(!value); } BaseTypePtr @@ -82,7 +82,7 @@ Real::plus(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<Real>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of + operator"); - return make_shared<Real>(value + btp2->value, env); + return make_shared<Real>(value + btp2->value); } BaseTypePtr @@ -91,7 +91,7 @@ Real::minus(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<Real>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of - operator"); - return make_shared<Real>(value - btp2->value, env); + return make_shared<Real>(value - btp2->value); } BaseTypePtr @@ -100,7 +100,7 @@ Real::times(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<Real>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of * operator"); - return make_shared<Real>(value * btp2->value, env); + return make_shared<Real>(value * btp2->value); } BaseTypePtr @@ -109,7 +109,7 @@ Real::divide(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<Real>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of / operator"); - return make_shared<Real>(value / btp2->value, env); + return make_shared<Real>(value / btp2->value); } BaseTypePtr @@ -118,7 +118,7 @@ Real::power(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<Real>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of ^ operator"); - return make_shared<Real>(pow(value, btp2->value), env); + return make_shared<Real>(pow(value, btp2->value)); } BoolPtr @@ -127,7 +127,7 @@ Real::is_less(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<Real>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of < operator"); - return make_shared<Bool>(isless(value, btp2->value), env); + return make_shared<Bool>(isless(value, btp2->value)); } BoolPtr @@ -136,7 +136,7 @@ Real::is_greater(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<Real>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of > operator"); - return make_shared<Bool>(isgreater(value, btp2->value), env); + return make_shared<Bool>(isgreater(value, btp2->value)); } BoolPtr @@ -145,7 +145,7 @@ Real::is_less_equal(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<Real>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of <= operator"); - return make_shared<Bool>(islessequal(value, btp2->value), env); + return make_shared<Bool>(islessequal(value, btp2->value)); } BoolPtr @@ -154,7 +154,7 @@ Real::is_greater_equal(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<Real>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of >= operator"); - return make_shared<Bool>(isgreaterequal(value, btp2->value), env); + return make_shared<Bool>(isgreaterequal(value, btp2->value)); } BoolPtr @@ -162,38 +162,38 @@ Real::is_equal(const BaseTypePtr &btp) const { auto btp2 = dynamic_pointer_cast<Real>(btp); if (!btp2) - return make_shared<Bool>(false, env); - return make_shared<Bool>(value == btp2->value, env); + return make_shared<Bool>(false); + return make_shared<Bool>(value == btp2->value); } BoolPtr -Real::logical_and(const ExpressionPtr &ep) const +Real::logical_and(const ExpressionPtr &ep, Environment &env) const { if (!value) - return make_shared<Bool>(false, env); + return make_shared<Bool>(false); - auto btp = ep->eval(); + auto btp = ep->eval(env); if (auto btp2 = dynamic_pointer_cast<Real>(btp); btp2) - return make_shared<Bool>(*btp2, env); + return make_shared<Bool>(*btp2); if (auto btp2 = dynamic_pointer_cast<Bool>(btp); btp2) - return make_shared<Bool>(*btp2, env); + return make_shared<Bool>(*btp2); throw StackTrace("Type mismatch for operands of && operator"); } BoolPtr -Real::logical_or(const ExpressionPtr &ep) const +Real::logical_or(const ExpressionPtr &ep, Environment &env) const { if (value) - return make_shared<Bool>(true, env); + return make_shared<Bool>(true); - auto btp = ep->eval(); + auto btp = ep->eval(env); if (auto btp2 = dynamic_pointer_cast<Real>(btp); btp2) - return make_shared<Bool>(*btp2, env); + return make_shared<Bool>(*btp2); if (auto btp2 = dynamic_pointer_cast<Bool>(btp); btp2) - return make_shared<Bool>(*btp2, env); + return make_shared<Bool>(*btp2); throw StackTrace("Type mismatch for operands of || operator"); } @@ -201,7 +201,7 @@ Real::logical_or(const ExpressionPtr &ep) const BoolPtr Real::logical_not() const { - return make_shared<Bool>(!value, env); + return make_shared<Bool>(!value); } RealPtr @@ -210,7 +210,7 @@ Real::max(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<Real>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of `max` operator"); - return make_shared<Real>(std::max(value, btp2->value), env); + return make_shared<Real>(std::max(value, btp2->value)); } RealPtr @@ -219,7 +219,7 @@ Real::min(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<Real>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of `min` operator"); - return make_shared<Real>(std::min(value, btp2->value), env); + return make_shared<Real>(std::min(value, btp2->value)); } RealPtr @@ -228,7 +228,7 @@ Real::mod(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<Real>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of `mod` operator"); - return make_shared<Real>(std::fmod(value, btp2->value), env); + return make_shared<Real>(std::fmod(value, btp2->value)); } RealPtr @@ -238,7 +238,7 @@ Real::normpdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const auto btp22 = dynamic_pointer_cast<Real>(btp2); if (!btp12 || !btp22) throw StackTrace("Type mismatch for operands of `normpdf` operator"); - return make_shared<Real>((1/(btp22->value*std::sqrt(2*M_PI)*std::exp(pow((value-btp12->value)/btp22->value, 2)/2))), env); + return make_shared<Real>((1/(btp22->value*std::sqrt(2*M_PI)*std::exp(pow((value-btp12->value)/btp22->value, 2)/2)))); } RealPtr @@ -248,7 +248,7 @@ Real::normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const auto btp22 = dynamic_pointer_cast<Real>(btp2); if (!btp12 || !btp22) throw StackTrace("Type mismatch for operands of `normpdf` operator"); - return make_shared<Real>((0.5*(1+std::erf((value-btp12->value)/btp22->value/M_SQRT2))), env); + return make_shared<Real>((0.5*(1+std::erf((value-btp12->value)/btp22->value/M_SQRT2)))); } BaseTypePtr @@ -257,7 +257,7 @@ String::plus(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<String>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of + operator"); - return make_shared<String>(value + btp2->value, env); + return make_shared<String>(value + btp2->value); } BoolPtr @@ -266,7 +266,7 @@ String::is_less(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<String>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of < operator"); - return make_shared<Bool>(value < btp2->value, env); + return make_shared<Bool>(value < btp2->value); } BoolPtr @@ -275,7 +275,7 @@ String::is_greater(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<String>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of > operator"); - return make_shared<Bool>(value > btp2->value, env); + return make_shared<Bool>(value > btp2->value); } BoolPtr @@ -284,7 +284,7 @@ String::is_less_equal(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<String>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of <= operator"); - return make_shared<Bool>(value <= btp2->value, env); + return make_shared<Bool>(value <= btp2->value); } BoolPtr @@ -293,7 +293,7 @@ String::is_greater_equal(const BaseTypePtr &btp) const auto btp2 = dynamic_pointer_cast<String>(btp); if (!btp2) throw StackTrace("Type mismatch for operands of >= operator"); - return make_shared<Bool>(value >= btp2->value, env); + return make_shared<Bool>(value >= btp2->value); } BoolPtr @@ -301,20 +301,20 @@ String::is_equal(const BaseTypePtr &btp) const { auto btp2 = dynamic_pointer_cast<String>(btp); if (!btp2) - return make_shared<Bool>(false, env); - return make_shared<Bool>(value == btp2->value, env); + return make_shared<Bool>(false); + return make_shared<Bool>(value == btp2->value); } BoolPtr -String::cast_bool() const +String::cast_bool(Environment &env) const { auto f = [](const char &a, const char &b) { return (tolower(a) == tolower(b)); }; if (string tf = "true"; equal(value.begin(), value.end(), tf.begin(), tf.end(), f)) - return make_shared<Bool>(true, env); + return make_shared<Bool>(true); if (string tf = "false"; equal(value.begin(), value.end(), tf.begin(), tf.end(), f)) - return make_shared<Bool>(false, env); + return make_shared<Bool>(false); try { @@ -322,7 +322,7 @@ String::cast_bool() const double value_d = stod(value, &pos); if (pos != value.length()) throw StackTrace("Entire string not converted"); - return make_shared<Bool>(static_cast<bool>(value_d), env); + return make_shared<Bool>(static_cast<bool>(value_d)); } catch (...) { @@ -331,7 +331,7 @@ String::cast_bool() const } RealPtr -String::cast_real() const +String::cast_real(Environment &env) const { try { @@ -339,7 +339,7 @@ String::cast_real() const double value_d = stod(value, &pos); if (pos != value.length()) throw StackTrace("Entire string not converted"); - return make_shared<Real>(value_d, env); + return make_shared<Real>(value_d); } catch (...) { @@ -356,7 +356,7 @@ Array::plus(const BaseTypePtr &btp) const vector<ExpressionPtr> arr_copy{arr}; arr_copy.insert(arr_copy.end(), btp2->arr.begin(), btp2->arr.end()); - return make_shared<Array>(arr_copy, env); + return make_shared<Array>(arr_copy); } BaseTypePtr @@ -379,7 +379,7 @@ Array::minus(const BaseTypePtr &btp) const if (it2 == btp2->arr.cend()) arr_copy.emplace_back(itbtp); } - return make_shared<Array>(arr_copy, env); + return make_shared<Array>(arr_copy); } BaseTypePtr @@ -409,10 +409,10 @@ Array::times(const BaseTypePtr &btp) const else throw StackTrace("Array::times: unsupported type on rhs"); - values.emplace_back(make_shared<Tuple>(new_tuple, env)); + values.emplace_back(make_shared<Tuple>(new_tuple)); } - return make_shared<Array>(values, env); + return make_shared<Array>(values); } BaseTypePtr @@ -422,11 +422,11 @@ Array::power(const BaseTypePtr &btp) const if (!btp2 || !*(btp2->isinteger())) throw StackTrace("The second argument of the power operator (^) must be an integer"); - auto retval = make_shared<Array>(arr, env); + auto retval = make_shared<Array>(arr); for (int i = 1; i < *btp2; i++) { - auto btpv = retval->times(make_shared<Array>(arr, env)); - retval = make_shared<Array>(dynamic_pointer_cast<Array>(btpv)->getValue(), env); + auto btpv = retval->times(make_shared<Array>(arr)); + retval = make_shared<Array>(dynamic_pointer_cast<Array>(btpv)->getValue()); } return retval; } @@ -436,19 +436,19 @@ Array::is_equal(const BaseTypePtr &btp) const { auto btp2 = dynamic_pointer_cast<Array>(btp); if (!btp2) - return make_shared<Bool>(false, env); + return make_shared<Bool>(false); if (arr.size() != btp2->arr.size()) - return make_shared<Bool>(false, env); + return make_shared<Bool>(false); for (size_t i = 0; i < arr.size(); i++) { auto bt = dynamic_pointer_cast<BaseType>(arr[i]); auto bt2 = dynamic_pointer_cast<BaseType>(btp2->arr[i]); if (!*(bt->is_equal(bt2))) - return make_shared<Bool>(false, env); + return make_shared<Bool>(false); } - return make_shared<Bool>(true, env); + return make_shared<Bool>(true); } ArrayPtr @@ -479,7 +479,7 @@ Array::set_union(const BaseTypePtr &btp) const if (!found) new_values.push_back(it); } - return make_shared<Array>(new_values, env); + return make_shared<Array>(new_values); } ArrayPtr @@ -507,7 +507,7 @@ Array::set_intersection(const BaseTypePtr &btp) const } } } - return make_shared<Array>(new_values, env); + return make_shared<Array>(new_values); } BoolPtr @@ -519,9 +519,9 @@ Array::contains(const BaseTypePtr &btp) const if (!v2) throw StackTrace("Type mismatch for operands of in operator"); if (*(v2->is_equal(btp))) - return make_shared<Bool>(true, env); + return make_shared<Bool>(true); } - return make_shared<Bool>(false, env); + return make_shared<Bool>(false); } RealPtr @@ -535,23 +535,23 @@ Array::sum() const throw StackTrace("Type mismatch for operands of in operator"); retval += *v2; } - return make_shared<Real>(retval, env); + return make_shared<Real>(retval); } BoolPtr -Array::cast_bool() const +Array::cast_bool(Environment &env) const { if (arr.size() != 1) throw StackTrace("Array must be of size 1 to be cast to a boolean"); - return arr.at(0)->eval()->cast_bool(); + return arr.at(0)->eval(env)->cast_bool(env); } RealPtr -Array::cast_real() const +Array::cast_real(Environment &env) const { if (arr.size() != 1) throw StackTrace("Array must be of size 1 to be cast to a real"); - return arr.at(0)->eval()->cast_real(); + return arr.at(0)->eval(env)->cast_real(env); } BoolPtr @@ -559,19 +559,19 @@ Tuple::is_equal(const BaseTypePtr &btp) const { auto btp2 = dynamic_pointer_cast<Tuple>(btp); if (!btp2) - return make_shared<Bool>(false, env); + return make_shared<Bool>(false); if (tup.size() != btp2->tup.size()) - return make_shared<Bool>(false, env); + return make_shared<Bool>(false); for (size_t i = 0; i < tup.size(); i++) { auto bt = dynamic_pointer_cast<BaseType>(tup[i]); auto bt2 = dynamic_pointer_cast<BaseType>(btp2->tup[i]); if (!*(bt->is_equal(bt2))) - return make_shared<Bool>(false, env); + return make_shared<Bool>(false); } - return make_shared<Bool>(true, env); + return make_shared<Bool>(true); } BoolPtr @@ -583,35 +583,35 @@ Tuple::contains(const BaseTypePtr &btp) const if (!v2) throw StackTrace("Type mismatch for operands of in operator"); if (*(v2->is_equal(btp))) - return make_shared<Bool>(true, env); + return make_shared<Bool>(true); } - return make_shared<Bool>(false, env); + return make_shared<Bool>(false); } BoolPtr -Tuple::cast_bool() const +Tuple::cast_bool(Environment &env) const { if (tup.size() != 1) throw StackTrace("Tuple must be of size 1 to be cast to a boolean"); - return tup.at(0)->eval()->cast_bool(); + return tup.at(0)->eval(env)->cast_bool(env); } RealPtr -Tuple::cast_real() const +Tuple::cast_real(Environment &env) const { if (tup.size() != 1) throw StackTrace("Tuple must be of size 1 to be cast to a real"); - return tup.at(0)->eval()->cast_real(); + return tup.at(0)->eval(env)->cast_real(env); } BaseTypePtr -Range::eval() +Range::eval(Environment &env) { - RealPtr incdbl = make_shared<Real>(1, env); + RealPtr incdbl = make_shared<Real>(1); if (inc) - incdbl = dynamic_pointer_cast<Real>(inc->eval()); - RealPtr startdbl = dynamic_pointer_cast<Real>(start->eval()); - RealPtr enddbl = dynamic_pointer_cast<Real>(end->eval()); + incdbl = dynamic_pointer_cast<Real>(inc->eval(env)); + RealPtr startdbl = dynamic_pointer_cast<Real>(start->eval(env)); + RealPtr enddbl = dynamic_pointer_cast<Real>(end->eval(env)); if (!startdbl || !enddbl || !incdbl) throw StackTrace("To create an array from a range using the colon operator, " "the arguments must evaluate to reals"); @@ -619,38 +619,38 @@ Range::eval() vector<ExpressionPtr> arr; if (*incdbl > 0 && *startdbl <= *enddbl) for (double i = *startdbl; i <= *enddbl; i += *incdbl) - arr.emplace_back(make_shared<Real>(i, env)); + arr.emplace_back(make_shared<Real>(i)); else if (*startdbl >= *enddbl && *incdbl < 0) for (double i = *startdbl; i >= *enddbl; i += *incdbl) - arr.emplace_back(make_shared<Real>(i, env)); + arr.emplace_back(make_shared<Real>(i)); - return make_shared<Array>(arr, env, location); + return make_shared<Array>(arr, location); } BaseTypePtr -Array::eval() +Array::eval(Environment &env) { vector<ExpressionPtr> retval; for (const auto &it : arr) - retval.emplace_back(it->eval()); - return make_shared<Array>(retval, env); + retval.emplace_back(it->eval(env)); + return make_shared<Array>(retval); } BaseTypePtr -Tuple::eval() +Tuple::eval(Environment &env) { vector<ExpressionPtr> retval; for (const auto &it : tup) - retval.emplace_back(it->eval()); - return make_shared<Tuple>(retval, env); + retval.emplace_back(it->eval(env)); + return make_shared<Tuple>(retval); } BaseTypePtr -Variable::eval() +Variable::eval(Environment &env) { if (indices && !indices->empty()) { - ArrayPtr map = dynamic_pointer_cast<Array>(indices->eval()); + ArrayPtr map = dynamic_pointer_cast<Array>(indices->eval(env)); vector<ExpressionPtr> index = map->getValue(); vector<int> ind; for (const auto &it : index) @@ -703,7 +703,7 @@ Variable::eval() { throw StackTrace("variable", "Index out of range", location); } - return make_shared<String>(retvals, env); + return make_shared<String>(retvals); } case codes::BaseType::Array: { @@ -712,7 +712,7 @@ Variable::eval() for (auto it : ind) try { - retval.emplace_back(ap->at(it - 1)->eval()); + retval.emplace_back(ap->at(it - 1)->eval(env)); } catch (const out_of_range &ex) { @@ -722,15 +722,15 @@ Variable::eval() if (retval.size() == 1) return retval.at(0); vector<ExpressionPtr> retvala(retval.begin(), retval.end()); - return make_shared<Array>(retvala, env); + return make_shared<Array>(retvala); } } } - return env.getVariable(name)->eval(); + return env.getVariable(name)->eval(env); } BaseTypePtr -Function::eval() +Function::eval(Environment &env) { FunctionPtr func; ExpressionPtr body; @@ -755,9 +755,9 @@ Function::eval() for (size_t i = 0; i < func->args.size(); i++) { VariablePtr mvp = dynamic_pointer_cast<Variable>(func->args.at(i)); - env.define(mvp, args.at(i)->eval()); + env.define(mvp, args.at(i)->eval(env)); } - auto retval = body->eval(); + auto retval = body->eval(env); env = env_orig; return retval; } @@ -769,90 +769,90 @@ Function::eval() } BaseTypePtr -UnaryOp::eval() +UnaryOp::eval(Environment &env) { try { switch (op_code) { case codes::UnaryOp::cast_bool: - return arg->eval()->cast_bool(); + return arg->eval(env)->cast_bool(env); case codes::UnaryOp::cast_real: - return arg->eval()->cast_real(); + return arg->eval(env)->cast_real(env); case codes::UnaryOp::cast_string: - return arg->eval()->cast_string(); + return arg->eval(env)->cast_string(); case codes::UnaryOp::cast_tuple: - return arg->eval()->cast_tuple(); + return arg->eval(env)->cast_tuple(); case codes::UnaryOp::cast_array: - return arg->eval()->cast_array(); + return arg->eval(env)->cast_array(); case codes::UnaryOp::logical_not: - return arg->eval()->logical_not(); + return arg->eval(env)->logical_not(); case codes::UnaryOp::unary_minus: - return arg->eval()->unary_minus(); + return arg->eval(env)->unary_minus(); case codes::UnaryOp::unary_plus: - return arg->eval()->unary_plus(); + return arg->eval(env)->unary_plus(); case codes::UnaryOp::length: - return arg->eval()->length(); + return arg->eval(env)->length(); case codes::UnaryOp::isempty: - return arg->eval()->isempty(); + return arg->eval(env)->isempty(); case codes::UnaryOp::isboolean: - return arg->eval()->isboolean(); + return arg->eval(env)->isboolean(); case codes::UnaryOp::isreal: - return arg->eval()->isreal(); + return arg->eval(env)->isreal(); case codes::UnaryOp::isstring: - return arg->eval()->isstring(); + return arg->eval(env)->isstring(); case codes::UnaryOp::istuple: - return arg->eval()->istuple(); + return arg->eval(env)->istuple(); case codes::UnaryOp::isarray: - return arg->eval()->isarray(); + return arg->eval(env)->isarray(); case codes::UnaryOp::exp: - return arg->eval()->exp(); + return arg->eval(env)->exp(); case codes::UnaryOp::ln: - return arg->eval()->ln(); + return arg->eval(env)->ln(); case codes::UnaryOp::log10: - return arg->eval()->log10(); + return arg->eval(env)->log10(); case codes::UnaryOp::sin: - return arg->eval()->sin(); + return arg->eval(env)->sin(); case codes::UnaryOp::cos: - return arg->eval()->cos(); + return arg->eval(env)->cos(); case codes::UnaryOp::tan: - return arg->eval()->tan(); + return arg->eval(env)->tan(); case codes::UnaryOp::asin: - return arg->eval()->asin(); + return arg->eval(env)->asin(); case codes::UnaryOp::acos: - return arg->eval()->acos(); + return arg->eval(env)->acos(); case codes::UnaryOp::atan: - return arg->eval()->atan(); + return arg->eval(env)->atan(); case codes::UnaryOp::sqrt: - return arg->eval()->sqrt(); + return arg->eval(env)->sqrt(); case codes::UnaryOp::cbrt: - return arg->eval()->cbrt(); + return arg->eval(env)->cbrt(); case codes::UnaryOp::sign: - return arg->eval()->sign(); + return arg->eval(env)->sign(); case codes::UnaryOp::floor: - return arg->eval()->floor(); + return arg->eval(env)->floor(); case codes::UnaryOp::ceil: - return arg->eval()->ceil(); + return arg->eval(env)->ceil(); case codes::UnaryOp::trunc: - return arg->eval()->trunc(); + return arg->eval(env)->trunc(); case codes::UnaryOp::sum: - return arg->eval()->sum(); + return arg->eval(env)->sum(); case codes::UnaryOp::erf: - return arg->eval()->erf(); + return arg->eval(env)->erf(); case codes::UnaryOp::erfc: - return arg->eval()->erfc(); + return arg->eval(env)->erfc(); case codes::UnaryOp::gamma: - return arg->eval()->gamma(); + return arg->eval(env)->gamma(); case codes::UnaryOp::lgamma: - return arg->eval()->lgamma(); + return arg->eval(env)->lgamma(); case codes::UnaryOp::round: - return arg->eval()->round(); + return arg->eval(env)->round(); case codes::UnaryOp::normpdf: - return arg->eval()->normpdf(); + return arg->eval(env)->normpdf(); case codes::UnaryOp::normcdf: - return arg->eval()->normcdf(); + return arg->eval(env)->normcdf(); case codes::UnaryOp::defined: - return arg->eval()->defined(); + return arg->eval(env)->defined(env); } } catch (StackTrace &ex) @@ -869,50 +869,50 @@ UnaryOp::eval() } BaseTypePtr -BinaryOp::eval() +BinaryOp::eval(Environment &env) { try { switch (op_code) { case codes::BinaryOp::plus: - return arg1->eval()->plus(arg2->eval()); + return arg1->eval(env)->plus(arg2->eval(env)); case codes::BinaryOp::minus: - return arg1->eval()->minus(arg2->eval()); + return arg1->eval(env)->minus(arg2->eval(env)); case codes::BinaryOp::times: - return arg1->eval()->times(arg2->eval()); + return arg1->eval(env)->times(arg2->eval(env)); case codes::BinaryOp::divide: - return arg1->eval()->divide(arg2->eval()); + return arg1->eval(env)->divide(arg2->eval(env)); case codes::BinaryOp::power: - return arg1->eval()->power(arg2->eval()); + return arg1->eval(env)->power(arg2->eval(env)); case codes::BinaryOp::equal_equal: - return arg1->eval()->is_equal(arg2->eval()); + return arg1->eval(env)->is_equal(arg2->eval(env)); case codes::BinaryOp::not_equal: - return arg1->eval()->is_different(arg2->eval()); + return arg1->eval(env)->is_different(arg2->eval(env)); case codes::BinaryOp::less: - return arg1->eval()->is_less(arg2->eval()); + return arg1->eval(env)->is_less(arg2->eval(env)); case codes::BinaryOp::greater: - return arg1->eval()->is_greater(arg2->eval()); + return arg1->eval(env)->is_greater(arg2->eval(env)); case codes::BinaryOp::less_equal: - return arg1->eval()->is_less_equal(arg2->eval()); + return arg1->eval(env)->is_less_equal(arg2->eval(env)); case codes::BinaryOp::greater_equal: - return arg1->eval()->is_greater_equal(arg2->eval()); + return arg1->eval(env)->is_greater_equal(arg2->eval(env)); case codes::BinaryOp::logical_and: - return arg1->eval()->logical_and(arg2); + return arg1->eval(env)->logical_and(arg2, env); case codes::BinaryOp::logical_or: - return arg1->eval()->logical_or(arg2); + return arg1->eval(env)->logical_or(arg2, env); case codes::BinaryOp::in: - return arg2->eval()->contains(arg1->eval()); + return arg2->eval(env)->contains(arg1->eval(env)); case codes::BinaryOp::set_union: - return arg1->eval()->set_union(arg2->eval()); + return arg1->eval(env)->set_union(arg2->eval(env)); case codes::BinaryOp::set_intersection: - return arg1->eval()->set_intersection(arg2->eval()); + return arg1->eval(env)->set_intersection(arg2->eval(env)); case codes::BinaryOp::max: - return arg1->eval()->max(arg2->eval()); + return arg1->eval(env)->max(arg2->eval(env)); case codes::BinaryOp::min: - return arg1->eval()->min(arg2->eval()); + return arg1->eval(env)->min(arg2->eval(env)); case codes::BinaryOp::mod: - return arg1->eval()->mod(arg2->eval()); + return arg1->eval(env)->mod(arg2->eval(env)); } } catch (StackTrace &ex) @@ -929,16 +929,16 @@ BinaryOp::eval() } BaseTypePtr -TrinaryOp::eval() +TrinaryOp::eval(Environment &env) { try { switch (op_code) { case codes::TrinaryOp::normpdf: - return arg1->eval()->normpdf(arg2->eval(), arg3->eval()); + return arg1->eval(env)->normpdf(arg2->eval(env), arg3->eval(env)); case codes::TrinaryOp::normcdf: - return arg1->eval()->normcdf(arg2->eval(), arg3->eval()); + return arg1->eval(env)->normcdf(arg2->eval(env), arg3->eval(env)); } } catch (StackTrace &ex) @@ -955,14 +955,14 @@ TrinaryOp::eval() } BaseTypePtr -Comprehension::eval() +Comprehension::eval(Environment &env) { ArrayPtr input_set; VariablePtr vp; TuplePtr mt; try { - input_set = dynamic_pointer_cast<Array>(c_set->eval()); + input_set = dynamic_pointer_cast<Array>(c_set->eval(env)); if (!input_set) throw StackTrace("Comprehension", "The input set must evaluate to an array", location); vp = dynamic_pointer_cast<Variable>(c_vars); @@ -1009,14 +1009,14 @@ Comprehension::eval() if (!c_expr) throw StackTrace("Comprehension", "Internal Error: Impossible case", location); else - values.emplace_back(c_expr->clone()->eval()); + values.emplace_back(c_expr->clone()->eval(env)); else { RealPtr dp; BoolPtr bp; try { - auto tmp = c_when->eval(); + auto tmp = c_when->eval(env); dp = dynamic_pointer_cast<Real>(tmp); bp = dynamic_pointer_cast<Bool>(tmp); if (!bp && !dp) @@ -1029,12 +1029,12 @@ Comprehension::eval() } if ((bp && *bp) || (dp && *dp)) if (c_expr) - values.emplace_back(c_expr->clone()->eval()); + values.emplace_back(c_expr->clone()->eval(env)); else values.emplace_back(btp); } } - return make_shared<Array>(values, env); + return make_shared<Array>(values); } ExpressionPtr @@ -1043,7 +1043,7 @@ Tuple::clone() const noexcept vector<ExpressionPtr> tup_copy; for (const auto &it : tup) tup_copy.emplace_back(it->clone()); - return make_shared<Tuple>(tup_copy, env, location); + return make_shared<Tuple>(tup_copy, location); } ExpressionPtr @@ -1052,7 +1052,7 @@ Array::clone() const noexcept vector<ExpressionPtr> arr_copy; for (const auto &it : arr) arr_copy.emplace_back(it->clone()); - return make_shared<Array>(arr_copy, env, location); + return make_shared<Array>(arr_copy, location); } ExpressionPtr @@ -1061,18 +1061,18 @@ Function::clone() const noexcept vector<ExpressionPtr> args_copy; for (const auto &it : args) args_copy.emplace_back(it->clone()); - return make_shared<Function>(name, args_copy, env, location); + return make_shared<Function>(name, args_copy, location); } ExpressionPtr Comprehension::clone() const noexcept { if (c_expr && c_when) - return make_shared<Comprehension>(c_expr->clone(), c_vars->clone(), c_set->clone(), c_when->clone(), env, location); + return make_shared<Comprehension>(c_expr->clone(), c_vars->clone(), c_set->clone(), c_when->clone(), location); else if (c_expr) - return make_shared<Comprehension>(c_expr->clone(), c_vars->clone(), c_set->clone(), env, location); + return make_shared<Comprehension>(c_expr->clone(), c_vars->clone(), c_set->clone(), location); else - return make_shared<Comprehension>(true, c_vars->clone(), c_set->clone(), c_when->clone(), env, location); + return make_shared<Comprehension>(true, c_vars->clone(), c_set->clone(), c_when->clone(), location); } string diff --git a/src/macro/Expressions.hh b/src/macro/Expressions.hh index ec7c69f17394f8af540a7e8b388ed6de5f5cb8c3..3715fd651c1e754ecbb384f7f1b0914a473398e6 100644 --- a/src/macro/Expressions.hh +++ b/src/macro/Expressions.hh @@ -81,11 +81,10 @@ namespace macro class Node { protected: - Environment &env; const Tokenizer::location location; public: - Node(Environment &env_arg, Tokenizer::location location_arg) : - env{env_arg}, location{move(location_arg)} { } + explicit Node(Tokenizer::location location_arg) : + location{move(location_arg)} { } virtual ~Node() = default; public: inline Tokenizer::location getLocation() const noexcept { return location; } @@ -113,11 +112,11 @@ namespace macro class Expression : public Node { public: - Expression(Environment &env_arg, Tokenizer::location location_arg) : - Node(env_arg, move(location_arg)) { } + explicit Expression(Tokenizer::location location_arg) : + Node(move(location_arg)) { } virtual string to_string() const noexcept = 0; virtual void print(ostream &output, bool matlab_output = false) const noexcept = 0; - virtual BaseTypePtr eval() = 0; + virtual BaseTypePtr eval(Environment &env) = 0; virtual ExpressionPtr clone() const noexcept = 0; }; @@ -125,10 +124,10 @@ namespace macro class BaseType : public Expression, public enable_shared_from_this<BaseType> { public: - BaseType(Environment &env_arg, Tokenizer::location location_arg = Tokenizer::location()) : - Expression(env_arg, move(location_arg)) { } + explicit BaseType(Tokenizer::location location_arg = Tokenizer::location()) : + Expression(move(location_arg)) { } virtual codes::BaseType getType() const noexcept = 0; - inline BaseTypePtr eval() override { return shared_from_this(); } + inline BaseTypePtr eval(Environment &env) override { return shared_from_this(); } public: virtual BaseTypePtr plus(const BaseTypePtr &bt) const { throw StackTrace("Operator + does not exist for this type"); } virtual BaseTypePtr unary_plus() const { throw StackTrace("Unary operator + does not exist for this type"); } @@ -143,20 +142,20 @@ namespace macro virtual BoolPtr is_greater_equal(const BaseTypePtr &btp) const { throw StackTrace("Operator >= does not exist for this type"); } virtual BoolPtr is_equal(const BaseTypePtr &btp) const = 0; virtual BoolPtr is_different(const BaseTypePtr &btp) const final; - virtual BoolPtr logical_and(const ExpressionPtr &ep) const { throw StackTrace("Operator && does not exist for this type"); } - virtual BoolPtr logical_or(const ExpressionPtr &ep) const { throw StackTrace("Operator || does not exist for this type"); } + virtual BoolPtr logical_and(const ExpressionPtr &ep, Environment &env) const { throw StackTrace("Operator && does not exist for this type"); } + virtual BoolPtr logical_or(const ExpressionPtr &ep, Environment &env) const { throw StackTrace("Operator || does not exist for this type"); } virtual BoolPtr logical_not() const { throw StackTrace("Operator ! does not exist for this type"); } virtual ArrayPtr set_union(const BaseTypePtr &btp) const { throw StackTrace("Operator | does not exist for this type"); } virtual ArrayPtr set_intersection(const BaseTypePtr &btp) const { throw StackTrace("Operator & does not exist for this type"); } virtual BoolPtr contains(const BaseTypePtr &btp) const { throw StackTrace("Second argument of `in` operator must be an array"); } virtual RealPtr length() const { throw StackTrace("Operator `length` does not exist for this type"); } virtual BoolPtr isempty() const { throw StackTrace("Operator `isempty` does not exist for this type"); } - virtual BoolPtr isboolean() const noexcept { return make_shared<Bool>(false, env, location); } - virtual BoolPtr isreal() const noexcept { return make_shared<Bool>(false, env, location); } - virtual BoolPtr isinteger() const noexcept { return make_shared<Bool>(false, env, location); } - virtual BoolPtr isstring() const noexcept { return make_shared<Bool>(false, env, location); } - virtual BoolPtr istuple() const noexcept { return make_shared<Bool>(false, env, location); } - virtual BoolPtr isarray() const noexcept { return make_shared<Bool>(false, env, location); } + virtual BoolPtr isboolean() const noexcept { return make_shared<Bool>(false, location); } + virtual BoolPtr isreal() const noexcept { return make_shared<Bool>(false, location); } + virtual BoolPtr isinteger() const noexcept { return make_shared<Bool>(false, location); } + virtual BoolPtr isstring() const noexcept { return make_shared<Bool>(false, location); } + virtual BoolPtr istuple() const noexcept { return make_shared<Bool>(false, location); } + virtual BoolPtr isarray() const noexcept { return make_shared<Bool>(false, location); } virtual RealPtr max(const BaseTypePtr &btp) const { throw StackTrace("Operator `max` does not exist for this type"); } virtual RealPtr min(const BaseTypePtr &btp) const { throw StackTrace("Operator `min` does not exist for this type"); } virtual RealPtr mod(const BaseTypePtr &btp) const { throw StackTrace("Operator `mod` does not exist for this type"); } @@ -189,12 +188,12 @@ namespace macro virtual RealPtr normpdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const { throw StackTrace("Operator `normpdf` does not exist for this type"); } virtual RealPtr normcdf() const { throw StackTrace("Operator `normcdf` does not exist for this type"); } virtual RealPtr normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const { throw StackTrace("Operator `normcdf` does not exist for this type"); } - virtual BoolPtr cast_bool() const { throw StackTrace("This type cannot be cast to a boolean"); } - virtual RealPtr cast_real() const { throw StackTrace("This type cannot be cast to a real"); } + virtual BoolPtr cast_bool(Environment &env) const { throw StackTrace("This type cannot be cast to a boolean"); } + virtual RealPtr cast_real(Environment &env) const { throw StackTrace("This type cannot be cast to a real"); } virtual StringPtr cast_string() const { throw StackTrace("This type cannot be cast to a string"); } virtual TuplePtr cast_tuple() const { throw StackTrace("This type cannot be cast to a tuple"); } virtual ArrayPtr cast_array() const { throw StackTrace("This type cannot be cast to an array"); } - virtual BoolPtr defined() const { throw StackTrace("Operator `defined` does not exist for this type"); } + virtual BoolPtr defined(const Environment &env) const { throw StackTrace("Operator `defined` does not exist for this type"); } }; @@ -204,30 +203,30 @@ namespace macro const bool value; public: Bool(bool value_arg, - Environment &env_arg, Tokenizer::location location_arg = Tokenizer::location()) : - BaseType(env_arg, move(location_arg)), + Tokenizer::location location_arg = Tokenizer::location()) : + BaseType(move(location_arg)), value{value_arg} { } inline codes::BaseType getType() const noexcept override { return codes::BaseType::Bool; } inline string to_string() const noexcept override { return value ? "true" : "false"; } inline void print(ostream &output, bool matlab_output = false) const noexcept override { output << to_string(); } - inline ExpressionPtr clone() const noexcept override { return make_shared<Bool>(value, env, location); } + inline ExpressionPtr clone() const noexcept override { return make_shared<Bool>(value, location); } public: operator bool() const { return value; } BoolPtr is_equal(const BaseTypePtr &btp) const override; - BoolPtr logical_and(const ExpressionPtr &ep) const override; - BoolPtr logical_or(const ExpressionPtr &ep) const override; + BoolPtr logical_and(const ExpressionPtr &ep, Environment &env) const override; + BoolPtr logical_or(const ExpressionPtr &ep, Environment &env) const override; BoolPtr logical_not() const override; - inline BoolPtr isboolean() const noexcept override { return make_shared<Bool>(true, env, location); } - inline BoolPtr cast_bool() const override { return make_shared<Bool>(value, env); } - inline RealPtr cast_real() const override { return value ? make_shared<Real>(1, env) : make_shared<Real>(0, env); } - inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); } + inline BoolPtr isboolean() const noexcept override { return make_shared<Bool>(true, location); } + inline BoolPtr cast_bool(Environment &env) const override { return make_shared<Bool>(value); } + inline RealPtr cast_real(Environment &env) const override { return value ? make_shared<Real>(1) : make_shared<Real>(0); } + inline StringPtr cast_string() const override { return make_shared<String>(this->to_string()); } inline TuplePtr cast_tuple() const override { - return make_shared<Tuple>(vector<ExpressionPtr>{make_shared<Bool>(value, env)}, env); + return make_shared<Tuple>(vector<ExpressionPtr>{make_shared<Bool>(value)}); } inline ArrayPtr cast_array() const override { - return make_shared<Array>(vector<ExpressionPtr>{make_shared<Bool>(value, env)}, env); + return make_shared<Array>(vector<ExpressionPtr>{make_shared<Bool>(value)}); } }; @@ -240,12 +239,12 @@ namespace macro // Use strtod to handle extreme cases (e.g. 1e500, 1e-500), nan, inf // See Note in NumericalConstants::AddNonNegativeConstant Real(const string &value_arg, - Environment &env_arg, Tokenizer::location location_arg = Tokenizer::location()) : - BaseType(env_arg, move(location_arg)), + Tokenizer::location location_arg = Tokenizer::location()) : + BaseType(move(location_arg)), value{strtod(value_arg.c_str(), nullptr)} { } Real(double value_arg, - Environment &env_arg, Tokenizer::location location_arg = Tokenizer::location()) : - BaseType(env_arg, move(location_arg)), + Tokenizer::location location_arg = Tokenizer::location()) : + BaseType(move(location_arg)), value{value_arg} { } inline codes::BaseType getType() const noexcept override { return codes::BaseType::Real; } inline string to_string() const noexcept override @@ -255,13 +254,13 @@ namespace macro return strs.str(); } inline void print(ostream &output, bool matlab_output = false) const noexcept override { output << to_string(); } - inline ExpressionPtr clone() const noexcept override { return make_shared<Real>(value, env, location); } + inline ExpressionPtr clone() const noexcept override { return make_shared<Real>(value, location); } public: operator double() const { return value; } BaseTypePtr plus(const BaseTypePtr &bt) const override; - inline BaseTypePtr unary_plus() const override { return make_shared<Real>(value, env); } + inline BaseTypePtr unary_plus() const override { return make_shared<Real>(value); } BaseTypePtr minus(const BaseTypePtr &bt) const override; - inline BaseTypePtr unary_minus() const override { return make_shared<Real>(-value, env); } + inline BaseTypePtr unary_minus() const override { return make_shared<Real>(-value); } BaseTypePtr times(const BaseTypePtr &bt) const override; BaseTypePtr divide(const BaseTypePtr &bt) const override; BaseTypePtr power(const BaseTypePtr &btp) const override; @@ -270,65 +269,65 @@ namespace macro BoolPtr is_less_equal(const BaseTypePtr &btp) const override; BoolPtr is_greater_equal(const BaseTypePtr &btp) const override; BoolPtr is_equal(const BaseTypePtr &btp) const override; - inline BoolPtr isreal() const noexcept override { return make_shared<Bool>(true, env, location); } + inline BoolPtr isreal() const noexcept override { return make_shared<Bool>(true, location); } inline BoolPtr isinteger() const noexcept override { double intpart; - return make_shared<Bool>(modf(value, &intpart) == 0.0, env, location); + return make_shared<Bool>(modf(value, &intpart) == 0.0, location); } - BoolPtr logical_and(const ExpressionPtr &ep) const override; - BoolPtr logical_or(const ExpressionPtr &ep) const override; + BoolPtr logical_and(const ExpressionPtr &ep, Environment &env) const override; + BoolPtr logical_or(const ExpressionPtr &ep, Environment &env) const override; BoolPtr logical_not() const override; RealPtr max(const BaseTypePtr &btp) const override; RealPtr min(const BaseTypePtr &btp) const override; RealPtr mod(const BaseTypePtr &btp) const override; - inline RealPtr exp() const override { return make_shared<Real>(std::exp(value), env); } - inline RealPtr ln() const override { return make_shared<Real>(std::log(value), env); } - inline RealPtr log10() const override { return make_shared<Real>(std::log10(value), env); } - inline BoolPtr isinf() const override { return make_shared<Bool>(std::isinf(value), env); } - inline BoolPtr isnan() const override { return make_shared<Bool>(std::isnan(value), env); } - inline BoolPtr isfinite() const override { return make_shared<Bool>(std::isfinite(value), env); } - inline BoolPtr isnormal() const override { return make_shared<Bool>(std::isnormal(value), env); } - inline RealPtr sin() const override { return make_shared<Real>(std::sin(value), env); } - inline RealPtr cos() const override { return make_shared<Real>(std::cos(value), env); } - inline RealPtr tan() const override { return make_shared<Real>(std::tan(value), env); } - inline RealPtr asin() const override { return make_shared<Real>(std::asin(value), env); } - inline RealPtr acos() const override { return make_shared<Real>(std::acos(value), env); } - inline RealPtr atan() const override { return make_shared<Real>(std::atan(value), env); } - inline RealPtr sqrt() const override { return make_shared<Real>(std::sqrt(value), env); } - inline RealPtr cbrt() const override { return make_shared<Real>(std::cbrt(value), env); } + inline RealPtr exp() const override { return make_shared<Real>(std::exp(value)); } + inline RealPtr ln() const override { return make_shared<Real>(std::log(value)); } + inline RealPtr log10() const override { return make_shared<Real>(std::log10(value)); } + inline BoolPtr isinf() const override { return make_shared<Bool>(std::isinf(value)); } + inline BoolPtr isnan() const override { return make_shared<Bool>(std::isnan(value)); } + inline BoolPtr isfinite() const override { return make_shared<Bool>(std::isfinite(value)); } + inline BoolPtr isnormal() const override { return make_shared<Bool>(std::isnormal(value)); } + inline RealPtr sin() const override { return make_shared<Real>(std::sin(value)); } + inline RealPtr cos() const override { return make_shared<Real>(std::cos(value)); } + inline RealPtr tan() const override { return make_shared<Real>(std::tan(value)); } + inline RealPtr asin() const override { return make_shared<Real>(std::asin(value)); } + inline RealPtr acos() const override { return make_shared<Real>(std::acos(value)); } + inline RealPtr atan() const override { return make_shared<Real>(std::atan(value)); } + inline RealPtr sqrt() const override { return make_shared<Real>(std::sqrt(value)); } + inline RealPtr cbrt() const override { return make_shared<Real>(std::cbrt(value)); } inline RealPtr sign() const override { - return make_shared<Real>((value > 0) ? 1. : ((value < 0) ? -1. : 0.), env); + return make_shared<Real>((value > 0) ? 1. : ((value < 0) ? -1. : 0.)); } - inline RealPtr floor() const override { return make_shared<Real>(std::floor(value), env); } - inline RealPtr ceil() const override { return make_shared<Real>(std::ceil(value), env); } - inline RealPtr trunc() const override { return make_shared<Real>(std::trunc(value), env); } - inline RealPtr erf() const override { return make_shared<Real>(std::erf(value), env); } - inline RealPtr erfc() const override { return make_shared<Real>(std::erfc(value), env); } - inline RealPtr gamma() const override { return make_shared<Real>(std::tgamma(value), env); } - inline RealPtr lgamma() const override { return make_shared<Real>(std::lgamma(value), env); } - inline RealPtr round() const override { return make_shared<Real>(std::round(value), env); } + inline RealPtr floor() const override { return make_shared<Real>(std::floor(value)); } + inline RealPtr ceil() const override { return make_shared<Real>(std::ceil(value)); } + inline RealPtr trunc() const override { return make_shared<Real>(std::trunc(value)); } + inline RealPtr erf() const override { return make_shared<Real>(std::erf(value)); } + inline RealPtr erfc() const override { return make_shared<Real>(std::erfc(value)); } + inline RealPtr gamma() const override { return make_shared<Real>(std::tgamma(value)); } + inline RealPtr lgamma() const override { return make_shared<Real>(std::lgamma(value)); } + inline RealPtr round() const override { return make_shared<Real>(std::round(value)); } inline RealPtr normpdf() const override { - return normpdf(make_shared<Real>(0, env), make_shared<Real>(1, env)); + return normpdf(make_shared<Real>(0), make_shared<Real>(1)); } RealPtr normpdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const override; inline RealPtr normcdf() const override { - return normcdf(make_shared<Real>(0, env), make_shared<Real>(1, env)); + return normcdf(make_shared<Real>(0), make_shared<Real>(1)); } RealPtr normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const override; - inline BoolPtr cast_bool() const override { return make_shared<Bool>(static_cast<bool>(value), env); } - inline RealPtr cast_real() const override { return make_shared<Real>(value, env); } - inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); } + inline BoolPtr cast_bool(Environment &env) const override { return make_shared<Bool>(static_cast<bool>(value)); } + inline RealPtr cast_real(Environment &env) const override { return make_shared<Real>(value); } + inline StringPtr cast_string() const override { return make_shared<String>(this->to_string()); } inline TuplePtr cast_tuple() const override { - return make_shared<Tuple>(vector<ExpressionPtr>{make_shared<Real>(value, env)}, env); + return make_shared<Tuple>(vector<ExpressionPtr>{make_shared<Real>(value)}); } inline ArrayPtr cast_array() const override { - return make_shared<Array>(vector<ExpressionPtr>{make_shared<Real>(value, env)}, env); + return make_shared<Array>(vector<ExpressionPtr>{make_shared<Real>(value)}); } }; @@ -338,13 +337,13 @@ namespace macro const string value; public: String(string value_arg, - Environment &env_arg, Tokenizer::location location_arg = Tokenizer::location()) : - BaseType(env_arg, move(location_arg)), + Tokenizer::location location_arg = Tokenizer::location()) : + BaseType(move(location_arg)), value{move(value_arg)} { } inline codes::BaseType getType() const noexcept override { return codes::BaseType::String; } inline string to_string() const noexcept override { return value; } void print(ostream &output, bool matlab_output = false) const noexcept override; - inline ExpressionPtr clone() const noexcept override { return make_shared<String>(value, env, location); } + inline ExpressionPtr clone() const noexcept override { return make_shared<String>(value, location); } public: operator string() const { return value; } BaseTypePtr plus(const BaseTypePtr &bt) const override; @@ -353,23 +352,23 @@ namespace macro BoolPtr is_less_equal(const BaseTypePtr &btp) const override; BoolPtr is_greater_equal(const BaseTypePtr &btp) const override; BoolPtr is_equal(const BaseTypePtr &btp) const override; - inline BoolPtr isstring() const noexcept override { return make_shared<Bool>(true, env, location); } - inline RealPtr length() const override { return make_shared<Real>(value.size(), env); } - inline BoolPtr isempty() const override { return make_shared<Bool>(value.empty(), env); } - BoolPtr cast_bool() const override; - RealPtr cast_real() const override; - inline StringPtr cast_string() const override { return make_shared<String>(value, env); } + inline BoolPtr isstring() const noexcept override { return make_shared<Bool>(true, location); } + inline RealPtr length() const override { return make_shared<Real>(value.size()); } + inline BoolPtr isempty() const override { return make_shared<Bool>(value.empty()); } + BoolPtr cast_bool(Environment &env) const override; + RealPtr cast_real(Environment &env) const override; + inline StringPtr cast_string() const override { return make_shared<String>(value); } inline TuplePtr cast_tuple() const override { - return make_shared<Tuple>(vector<ExpressionPtr>{make_shared<String>(value, env)}, env); + return make_shared<Tuple>(vector<ExpressionPtr>{make_shared<String>(value)}); } inline ArrayPtr cast_array() const override { - return make_shared<Array>(vector<ExpressionPtr>{make_shared<String>(value, env)}, env); + return make_shared<Array>(vector<ExpressionPtr>{make_shared<String>(value)}); } - inline BoolPtr defined() const override + inline BoolPtr defined(const Environment &env) const override { - return make_shared<Bool>(env.isSymbolDefined(value), env); + return make_shared<Bool>(env.isSymbolDefined(value)); } }; @@ -380,13 +379,13 @@ namespace macro const vector<ExpressionPtr> tup; public: Tuple(vector<ExpressionPtr> tup_arg, - Environment &env_arg, Tokenizer::location location_arg = Tokenizer::location()) : - BaseType(env_arg, move(location_arg)), + Tokenizer::location location_arg = Tokenizer::location()) : + BaseType(move(location_arg)), tup{move(tup_arg)} { } inline codes::BaseType getType() const noexcept override { return codes::BaseType::Tuple; } string to_string() const noexcept override; void print(ostream &output, bool matlab_output = false) const noexcept override; - BaseTypePtr eval() override; + BaseTypePtr eval(Environment &env) override; ExpressionPtr clone() const noexcept override; public: inline size_t size() const { return tup.size(); } @@ -394,15 +393,15 @@ namespace macro inline const vector<ExpressionPtr> &getValue() const { return tup; } inline const ExpressionPtr &at(int i) const { return tup.at(i); } BoolPtr is_equal(const BaseTypePtr &btp) const override; - inline BoolPtr istuple() const noexcept override { return make_shared<Bool>(true, env, location); } + inline BoolPtr istuple() const noexcept override { return make_shared<Bool>(true, location); } BoolPtr contains(const BaseTypePtr &btp) const override; - inline RealPtr length() const override { return make_shared<Real>(tup.size(), env); } - inline BoolPtr isempty() const override { return make_shared<Bool>(empty(), env); } - BoolPtr cast_bool() const override; - RealPtr cast_real() const override; - inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); } - inline TuplePtr cast_tuple() const override { return make_shared<Tuple>(tup, env); } - inline ArrayPtr cast_array() const override { return make_shared<Array>(tup, env); } + inline RealPtr length() const override { return make_shared<Real>(tup.size()); } + inline BoolPtr isempty() const override { return make_shared<Bool>(empty()); } + BoolPtr cast_bool(Environment &env) const override; + RealPtr cast_real(Environment &env) const override; + inline StringPtr cast_string() const override { return make_shared<String>(this->to_string()); } + inline TuplePtr cast_tuple() const override { return make_shared<Tuple>(tup); } + inline ArrayPtr cast_array() const override { return make_shared<Array>(tup); } }; @@ -412,12 +411,12 @@ namespace macro const vector<ExpressionPtr> arr; public: Array(vector<ExpressionPtr> arr_arg, - Environment &env_arg, Tokenizer::location location_arg = Tokenizer::location()) : - BaseType(env_arg, move(location_arg)), arr{move(arr_arg)} { } + Tokenizer::location location_arg = Tokenizer::location()) : + BaseType(move(location_arg)), arr{move(arr_arg)} { } inline codes::BaseType getType() const noexcept override { return codes::BaseType::Array; } string to_string() const noexcept override; void print(ostream &output, bool matlab_output = false) const noexcept override; - BaseTypePtr eval() override; + BaseTypePtr eval(Environment &env) override; ExpressionPtr clone() const noexcept override; public: inline size_t size() const { return arr.size(); } @@ -429,18 +428,18 @@ namespace macro BaseTypePtr times(const BaseTypePtr &bt) const override; BaseTypePtr power(const BaseTypePtr &btp) const override; BoolPtr is_equal(const BaseTypePtr &btp) const override; - inline BoolPtr isarray() const noexcept override { return make_shared<Bool>(true, env, location); } + inline BoolPtr isarray() const noexcept override { return make_shared<Bool>(true, location); } ArrayPtr set_union(const BaseTypePtr &btp) const override; ArrayPtr set_intersection(const BaseTypePtr &btp) const override; BoolPtr contains(const BaseTypePtr &btp) const override; - inline RealPtr length() const override { return make_shared<Real>(arr.size(), env); } - inline BoolPtr isempty() const override { return make_shared<Bool>(empty(), env); } + inline RealPtr length() const override { return make_shared<Real>(arr.size()); } + inline BoolPtr isempty() const override { return make_shared<Bool>(empty()); } RealPtr sum() const override; - BoolPtr cast_bool() const override; - RealPtr cast_real() const override; - inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); } - inline TuplePtr cast_tuple() const override { return make_shared<Tuple>(arr, env); } - inline ArrayPtr cast_array() const override { return make_shared<Array>(arr, env); } + BoolPtr cast_bool(Environment &env) const override; + RealPtr cast_real(Environment &env) const override; + inline StringPtr cast_string() const override { return make_shared<String>(this->to_string()); } + inline TuplePtr cast_tuple() const override { return make_shared<Tuple>(arr); } + inline ArrayPtr cast_array() const override { return make_shared<Array>(arr); } }; @@ -450,11 +449,11 @@ namespace macro const ExpressionPtr start, inc, end; public: Range(ExpressionPtr start_arg, ExpressionPtr end_arg, - Environment &env_arg, Tokenizer::location location_arg) : - BaseType(env_arg, move(location_arg)), start{move(start_arg)}, end{move(end_arg)} { } + Tokenizer::location location_arg) : + BaseType(move(location_arg)), start{move(start_arg)}, end{move(end_arg)} { } Range(ExpressionPtr start_arg, ExpressionPtr inc_arg, ExpressionPtr end_arg, - Environment &env_arg, Tokenizer::location location_arg) : - BaseType(env_arg, move(location_arg)), + Tokenizer::location location_arg) : + BaseType(move(location_arg)), start{move(start_arg)}, inc{move(inc_arg)}, end{move(end_arg)} { } inline codes::BaseType getType() const noexcept override { return codes::BaseType::Range; } inline string to_string() const noexcept override @@ -465,12 +464,12 @@ namespace macro return retval + end->to_string() + "]"; } inline void print(ostream &output, bool matlab_output = false) const noexcept override { output << to_string(); } - BaseTypePtr eval() override; + BaseTypePtr eval(Environment &env) override; inline ExpressionPtr clone() const noexcept override { return inc ? - make_shared<Range>(start, inc, end, env, location) - : make_shared<Range>(start, end, env, location); + make_shared<Range>(start, inc, end, location) + : make_shared<Range>(start, end, location); } public: inline BoolPtr is_equal(const BaseTypePtr &btp) const override @@ -487,22 +486,22 @@ namespace macro const ArrayPtr indices; // for indexing strings/arrays public: Variable(string name_arg, - Environment &env_arg, Tokenizer::location location_arg) : - Expression(env_arg, move(location_arg)), name{move(name_arg)} { } + Tokenizer::location location_arg) : + Expression(move(location_arg)), name{move(name_arg)} { } Variable(string name_arg, ArrayPtr indices_arg, - Environment &env_arg, Tokenizer::location location_arg) : - Expression(env_arg, move(location_arg)), name{move(name_arg)}, indices{move(indices_arg)} { } + Tokenizer::location location_arg) : + Expression(move(location_arg)), name{move(name_arg)}, indices{move(indices_arg)} { } inline string to_string() const noexcept override { return name; } inline void print(ostream &output, bool matlab_output = false) const noexcept override { output << name; } - BaseTypePtr eval() override; + BaseTypePtr eval(Environment &env) override; inline ExpressionPtr clone() const noexcept override { - return indices ? make_shared<Variable>(name, indices, env, location) : - make_shared<Variable>(name, env, location); + return indices ? make_shared<Variable>(name, indices, location) : + make_shared<Variable>(name, location); } public: inline const string &getName() const noexcept { return name; } - inline codes::BaseType getType() const { return env.getType(name); } + inline codes::BaseType getType(const Environment &env) const { return env.getType(name); } }; @@ -514,14 +513,14 @@ namespace macro public: Function(string name_arg, vector<ExpressionPtr> args_arg, - Environment &env_arg, Tokenizer::location location_arg) : - Expression(env_arg, move(location_arg)), name{move(name_arg)}, args{move(args_arg)} { } + Tokenizer::location location_arg) : + Expression(move(location_arg)), name{move(name_arg)}, args{move(args_arg)} { } string to_string() const noexcept override; inline void print(ostream &output, bool matlab_output = false) const noexcept override { printName(output); printArgs(output); } - BaseTypePtr eval() override; + BaseTypePtr eval(Environment &env) override; ExpressionPtr clone() const noexcept override; public: inline void printName(ostream &output) const noexcept { output << name; } @@ -539,14 +538,14 @@ namespace macro public: UnaryOp(codes::UnaryOp op_code_arg, ExpressionPtr arg_arg, - Environment &env_arg, Tokenizer::location location_arg) : - Expression(env_arg, move(location_arg)), op_code{move(op_code_arg)}, arg{move(arg_arg)} { } + Tokenizer::location location_arg) : + Expression(move(location_arg)), op_code{move(op_code_arg)}, arg{move(arg_arg)} { } string to_string() const noexcept override; void print(ostream &output, bool matlab_output = false) const noexcept override; - BaseTypePtr eval() override; + BaseTypePtr eval(Environment &env) override; inline ExpressionPtr clone() const noexcept override { - return make_shared<UnaryOp>(op_code, arg->clone(), env, location); + return make_shared<UnaryOp>(op_code, arg->clone(), location); } }; @@ -559,16 +558,16 @@ namespace macro public: BinaryOp(codes::BinaryOp op_code_arg, ExpressionPtr arg1_arg, ExpressionPtr arg2_arg, - Environment &env_arg, Tokenizer::location location_arg) : - Expression(env_arg, move(location_arg)), op_code{op_code_arg}, + Tokenizer::location location_arg) : + Expression(move(location_arg)), op_code{op_code_arg}, arg1{move(arg1_arg)}, arg2{move(arg2_arg)} { } public: string to_string() const noexcept override; void print(ostream &output, bool matlab_output = false) const noexcept override; - BaseTypePtr eval() override; + BaseTypePtr eval(Environment &env) override; inline ExpressionPtr clone() const noexcept override { - return make_shared<BinaryOp>(op_code, arg1->clone(), arg2->clone(), env, location); + return make_shared<BinaryOp>(op_code, arg1->clone(), arg2->clone(), location); } }; @@ -581,15 +580,15 @@ namespace macro public: TrinaryOp(codes::TrinaryOp op_code_arg, ExpressionPtr arg1_arg, ExpressionPtr arg2_arg, ExpressionPtr arg3_arg, - Environment &env_arg, Tokenizer::location location_arg) : - Expression(env_arg, move(location_arg)), op_code{op_code_arg}, + Tokenizer::location location_arg) : + Expression(move(location_arg)), op_code{op_code_arg}, arg1{move(arg1_arg)}, arg2{move(arg2_arg)}, arg3{move(arg3_arg)} { } string to_string() const noexcept override; void print(ostream &output, bool matlab_output = false) const noexcept override; - BaseTypePtr eval() override; + BaseTypePtr eval(Environment &env) override; inline ExpressionPtr clone() const noexcept override { - return make_shared<TrinaryOp>(op_code, arg1->clone(), arg2->clone(), arg3->clone(), env, location); + return make_shared<TrinaryOp>(op_code, arg1->clone(), arg2->clone(), arg3->clone(), location); } }; @@ -608,26 +607,26 @@ namespace macro ExpressionPtr c_vars_arg, ExpressionPtr c_set_arg, ExpressionPtr c_when_arg, - Environment &env_arg, Tokenizer::location location_arg) : - Expression(env_arg, move(location_arg)), + Tokenizer::location location_arg) : + Expression(move(location_arg)), c_expr{move(c_expr_arg)}, c_vars{move(c_vars_arg)}, c_set{move(c_set_arg)}, c_when{move(c_when_arg)} { } Comprehension(ExpressionPtr c_expr_arg, ExpressionPtr c_vars_arg, ExpressionPtr c_set_arg, - Environment &env_arg, Tokenizer::location location_arg) : - Expression(env_arg, move(location_arg)), + Tokenizer::location location_arg) : + Expression(move(location_arg)), c_expr{move(c_expr_arg)}, c_vars{move(c_vars_arg)}, c_set{move(c_set_arg)} { } Comprehension(bool filter_only_arg, ExpressionPtr c_vars_arg, ExpressionPtr c_set_arg, ExpressionPtr c_when_arg, - Environment &env_arg, Tokenizer::location location_arg) : - Expression(env_arg, move(location_arg)), + Tokenizer::location location_arg) : + Expression(move(location_arg)), c_vars{move(c_vars_arg)}, c_set{move(c_set_arg)}, c_when{move(c_when_arg)} { } string to_string() const noexcept override; void print(ostream &output, bool matlab_output = false) const noexcept override; - BaseTypePtr eval() override; + BaseTypePtr eval(Environment &env) override; ExpressionPtr clone() const noexcept override; }; } diff --git a/src/macro/Parser.yy b/src/macro/Parser.yy index 2c72ea84cf0182549aeafc53c91eba5d8ed7a5af..9537824c8130a10a4532f6ea597a44b9ea909a7f 100644 --- a/src/macro/Parser.yy +++ b/src/macro/Parser.yy @@ -126,35 +126,35 @@ directive : directive_one_line EOL ; directive_one_line : INCLUDE expr - { $$ = make_shared<Include>($2, driver.env, @$); } + { $$ = make_shared<Include>($2, @$); } | INCLUDEPATH expr - { $$ = make_shared<IncludePath>($2, driver.env, @$); } + { $$ = make_shared<IncludePath>($2, @$); } | DEFINE symbol { - auto tmp = make_shared<Real>("1", driver.env, @$); - $$ = make_shared<Define>($2, tmp, driver.env, @$); + auto tmp = make_shared<Real>("1", @$); + $$ = make_shared<Define>($2, tmp, @$); } | DEFINE symbol EQUAL expr - { $$ = make_shared<Define>($2, $4, driver.env, @$); } + { $$ = make_shared<Define>($2, $4, @$); } | DEFINE function EQUAL expr - { $$ = make_shared<Define>($2, $4, driver.env, @$); } + { $$ = make_shared<Define>($2, $4, @$); } | D_ECHO expr - { $$ = make_shared<Echo>($2, driver.env, @$); } + { $$ = make_shared<Echo>($2, @$); } | ERROR expr - { $$ = make_shared<Error>($2, driver.env, @$); } + { $$ = make_shared<Error>($2, @$); } | ECHOMACROVARS - { $$ = make_shared<EchoMacroVars>(false, driver.env, @$); } + { $$ = make_shared<EchoMacroVars>(false, @$); } | ECHOMACROVARS name_list - { $$ = make_shared<EchoMacroVars>(false, $2, driver.env, @$); } + { $$ = make_shared<EchoMacroVars>(false, $2, @$); } | ECHOMACROVARS LPAREN SAVE RPAREN - { $$ = make_shared<EchoMacroVars>(true, driver.env, @$); } + { $$ = make_shared<EchoMacroVars>(true, @$); } | ECHOMACROVARS LPAREN SAVE RPAREN name_list - { $$ = make_shared<EchoMacroVars>(true, $5, driver.env, @$); } + { $$ = make_shared<EchoMacroVars>(true, $5, @$); } | LINE QUOTED_STRING NUMBER { // `@#line` is ignored; adjust newlines in output to accord auto l = static_cast<Tokenizer::parser::location_type>(@$); - $$ = make_shared<TextNode>(string(l.end.line - l.begin.line + 1, '\n'), driver.env, @$); + $$ = make_shared<TextNode>(string(l.end.line - l.begin.line + 1, '\n'), @$); } ; @@ -198,28 +198,28 @@ for : FOR { driver.pushContext(); } expr IN expr for_when EOL statements ENDFOR error(@1, "For loop indices must be a variable or a tuple"); auto vdp = driver.popContext(); - vdp.emplace_back(make_shared<TextNode>("\n", driver.env, @9)); + vdp.emplace_back(make_shared<TextNode>("\n", @9)); if (!$6) - $$ = make_shared<For>(vvnp, $5, vdp, driver.env, @$); + $$ = make_shared<For>(vvnp, $5, vdp, @$); else { - auto tmpc = make_shared<Comprehension>(true, $3, $5, $6, driver.env, @6); - $$ = make_shared<For>(vvnp, tmpc, vdp, driver.env, @$); + auto tmpc = make_shared<Comprehension>(true, $3, $5, $6, @6); + $$ = make_shared<For>(vvnp, tmpc, vdp, @$); } } ; if : IF { driver.pushContext(); } if_list ENDIF - { $$ = make_shared<If>($3, driver.env, @$); } + { $$ = make_shared<If>($3, @$); } ; ifdef : IFDEF { driver.pushContext(); } if_list ENDIF - { $$ = make_shared<Ifdef>($3, driver.env, @$); } + { $$ = make_shared<Ifdef>($3, @$); } ; ifndef : IFNDEF { driver.pushContext(); } if_list ENDIF - { $$ = make_shared<Ifndef>($3, driver.env, @$); } + { $$ = make_shared<Ifndef>($3, @$); } ; if_list : if_list1 @@ -233,13 +233,13 @@ if_list : if_list1 if_list1 : expr EOL { auto context = driver.popContext(); - context.emplace_back(make_shared<TextNode>("\n", driver.env, @2)); + context.emplace_back(make_shared<TextNode>("\n", @2)); $$ = {{$1, context}}; } | expr EOL statements { auto context = driver.popContext(); - context.emplace_back(make_shared<TextNode>("\n", driver.env, @3)); + context.emplace_back(make_shared<TextNode>("\n", @3)); $$ = {{$1, context}}; } | if_list1 elseif @@ -254,13 +254,13 @@ elseif_begin : ELSEIF { driver.pushContext(); } ; elseif : elseif_begin expr EOL { auto context = driver.popContext(); - context.emplace_back(make_shared<TextNode>("\n", driver.env, @3)); + context.emplace_back(make_shared<TextNode>("\n", @3)); $$ = {$2, context}; } | elseif_begin expr EOL statements { auto context = driver.popContext(); - context.emplace_back(make_shared<TextNode>("\n", driver.env, @4)); + context.emplace_back(make_shared<TextNode>("\n", @4)); $$ = {$2, context}; } ; @@ -270,35 +270,35 @@ else_begin : ELSE { driver.pushContext(); } ; else : else_begin EOL { auto context = driver.popContext(); - context.emplace_back(make_shared<TextNode>("\n", driver.env, @2)); - $$ = {make_shared<Bool>(true, driver.env, @1), context}; + context.emplace_back(make_shared<TextNode>("\n", @2)); + $$ = {make_shared<Bool>(true, @1), context}; } | else_begin EOL statements { auto context = driver.popContext(); - context.emplace_back(make_shared<TextNode>("\n", driver.env, @3)); - $$ = {make_shared<Bool>(true, driver.env, @1), context}; + context.emplace_back(make_shared<TextNode>("\n", @3)); + $$ = {make_shared<Bool>(true, @1), context}; } ; text : TEXT - { $$ = make_shared<TextNode>($1, driver.env, @$); } + { $$ = make_shared<TextNode>($1, @$); } | EOL - { $$ = make_shared<TextNode>($1, driver.env, @$); } + { $$ = make_shared<TextNode>($1, @$); } ; eval : BEGIN_EVAL expr END_EVAL - { $$ = make_shared<Eval>($2, driver.env, @$); } + { $$ = make_shared<Eval>($2, @$); } ; symbol : NAME - { $$ = make_shared<Variable>($1, driver.env, @$); } + { $$ = make_shared<Variable>($1, @$); } ; function : NAME LPAREN RPAREN - { $$ = make_shared<Function>($1, vector<ExpressionPtr>(), driver.env, @$); } + { $$ = make_shared<Function>($1, vector<ExpressionPtr>(), @$); } | NAME LPAREN function_args RPAREN - { $$ = make_shared<Function>($1, $3, driver.env, @$); } + { $$ = make_shared<Function>($1, $3, @$); } ; function_args : symbol @@ -331,164 +331,163 @@ primary_expr : LPAREN expr RPAREN { $$ = $1; } // Explicit rule needed for type conversion | NAME LBRACKET comma_expr RBRACKET { - $$ = make_shared<Variable>($1, make_shared<Array>($3, driver.env, @3), - driver.env, @$); + $$ = make_shared<Variable>($1, make_shared<Array>($3, @3), @$); } | NAME LPAREN comma_expr RPAREN - { $$ = make_shared<Function>($1, $3, driver.env, @$); } + { $$ = make_shared<Function>($1, $3, @$); } | TRUE - { $$ = make_shared<Bool>(true, driver.env, @$); } + { $$ = make_shared<Bool>(true, @$); } | FALSE - { $$ = make_shared<Bool>(false, driver.env, @$); } + { $$ = make_shared<Bool>(false, @$); } | NUMBER - { $$ = make_shared<Real>($1, driver.env, @$); } + { $$ = make_shared<Real>($1, @$); } | QUOTED_STRING - { $$ = make_shared<String>($1, driver.env, @$); } + { $$ = make_shared<String>($1, @$); } | LBRACKET comma_expr RBRACKET - { $$ = make_shared<Array>($2, driver.env, @$); } + { $$ = make_shared<Array>($2, @$); } | LPAREN tuple_comma_expr RPAREN - { $$ = make_shared<Tuple>($2, driver.env, @$); } + { $$ = make_shared<Tuple>($2, @$); } | LBRACKET expr IN expr WHEN expr RBRACKET - { $$ = make_shared<Comprehension>(true, $2, $4, $6, driver.env, @$); } + { $$ = make_shared<Comprehension>(true, $2, $4, $6, @$); } | LBRACKET expr FOR expr IN expr RBRACKET - { $$ = make_shared<Comprehension>($2, $4, $6, driver.env, @$); } + { $$ = make_shared<Comprehension>($2, $4, $6, @$); } | LBRACKET expr FOR expr IN expr WHEN expr RBRACKET - { $$ = make_shared<Comprehension>($2, $4, $6, $8, driver.env, @$); } + { $$ = make_shared<Comprehension>($2, $4, $6, $8, @$); } | LENGTH LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::length, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::length, $3, @$); } | ISEMPTY LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::isempty, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::isempty, $3, @$); } | ISBOOLEAN LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::isboolean, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::isboolean, $3, @$); } | ISREAL LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::isreal, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::isreal, $3, @$); } | ISSTRING LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::isstring, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::isstring, $3, @$); } | ISTUPLE LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::istuple, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::istuple, $3, @$); } | ISARRAY LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::isarray, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::isarray, $3, @$); } | EXP LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::exp, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::exp, $3, @$); } | LOG LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::ln, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::ln, $3, @$); } | LN LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::ln, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::ln, $3, @$); } | LOG10 LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::log10, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::log10, $3, @$); } | SIN LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::sin, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::sin, $3, @$); } | COS LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::cos, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::cos, $3, @$); } | TAN LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::tan, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::tan, $3, @$); } | ASIN LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::asin, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::asin, $3, @$); } | ACOS LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::acos, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::acos, $3, @$); } | ATAN LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::atan, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::atan, $3, @$); } | SQRT LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::sqrt, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::sqrt, $3, @$); } | CBRT LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::cbrt, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::cbrt, $3, @$); } | SIGN LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::sign, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::sign, $3, @$); } | FLOOR LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::floor, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::floor, $3, @$); } | CEIL LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::ceil, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::ceil, $3, @$); } | TRUNC LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::trunc, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::trunc, $3, @$); } | SUM LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::sum, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::sum, $3, @$); } | ERF LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::erf, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::erf, $3, @$); } | ERFC LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::erfc, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::erfc, $3, @$); } | GAMMA LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::gamma, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::gamma, $3, @$); } | LGAMMA LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::lgamma, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::lgamma, $3, @$); } | ROUND LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::round, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::round, $3, @$); } | NORMPDF LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::normpdf, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::normpdf, $3, @$); } | NORMCDF LPAREN expr RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::normcdf, $3, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::normcdf, $3, @$); } | MAX LPAREN expr COMMA expr RPAREN - { $$ = make_shared<BinaryOp>(codes::BinaryOp::max, $3, $5, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::max, $3, $5, @$); } | MIN LPAREN expr COMMA expr RPAREN - { $$ = make_shared<BinaryOp>(codes::BinaryOp::min, $3, $5, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::min, $3, $5, @$); } | MOD LPAREN expr COMMA expr RPAREN - { $$ = make_shared<BinaryOp>(codes::BinaryOp::mod, $3, $5, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::mod, $3, $5, @$); } | NORMPDF LPAREN expr COMMA expr COMMA expr RPAREN - { $$ = make_shared<TrinaryOp>(codes::TrinaryOp::normpdf, $3, $5, $7, driver.env, @$); } + { $$ = make_shared<TrinaryOp>(codes::TrinaryOp::normpdf, $3, $5, $7, @$); } | NORMCDF LPAREN expr COMMA expr COMMA expr RPAREN - { $$ = make_shared<TrinaryOp>(codes::TrinaryOp::normcdf, $3, $5, $7, driver.env, @$); } + { $$ = make_shared<TrinaryOp>(codes::TrinaryOp::normcdf, $3, $5, $7, @$); } | DEFINED LPAREN NAME RPAREN - { $$ = make_shared<UnaryOp>(codes::UnaryOp::defined, make_shared<String>($3, driver.env, @3), driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::defined, make_shared<String>($3, @3), @$); } ; oper_expr : primary_expr | LPAREN BOOL RPAREN oper_expr %prec CAST - { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_bool, $4, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_bool, $4, @$); } | LPAREN REAL RPAREN oper_expr %prec CAST - { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_real, $4, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_real, $4, @$); } | LPAREN STRING RPAREN oper_expr %prec CAST - { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_string, $4, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_string, $4, @$); } | LPAREN TUPLE RPAREN oper_expr %prec CAST - { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_tuple, $4, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_tuple, $4, @$); } | LPAREN ARRAY RPAREN oper_expr %prec CAST - { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_array, $4, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_array, $4, @$); } | NOT oper_expr - { $$ = make_shared<UnaryOp>(codes::UnaryOp::logical_not, $2, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::logical_not, $2, @$); } | MINUS oper_expr %prec UNARY - { $$ = make_shared<UnaryOp>(codes::UnaryOp::unary_minus, $2, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::unary_minus, $2, @$); } | PLUS oper_expr %prec UNARY - { $$ = make_shared<UnaryOp>(codes::UnaryOp::unary_plus, $2, driver.env, @$); } + { $$ = make_shared<UnaryOp>(codes::UnaryOp::unary_plus, $2, @$); } | oper_expr PLUS oper_expr - { $$ = make_shared<BinaryOp>(codes::BinaryOp::plus, $1, $3, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::plus, $1, $3, @$); } | oper_expr MINUS oper_expr - { $$ = make_shared<BinaryOp>(codes::BinaryOp::minus, $1, $3, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::minus, $1, $3, @$); } | oper_expr TIMES oper_expr - { $$ = make_shared<BinaryOp>(codes::BinaryOp::times, $1, $3, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::times, $1, $3, @$); } | oper_expr DIVIDE oper_expr - { $$ = make_shared<BinaryOp>(codes::BinaryOp::divide, $1, $3, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::divide, $1, $3, @$); } | oper_expr POWER oper_expr - { $$ = make_shared<BinaryOp>(codes::BinaryOp::power, $1, $3, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::power, $1, $3, @$); } | oper_expr UNION oper_expr - { $$ = make_shared<BinaryOp>(codes::BinaryOp::set_union, $1, $3, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::set_union, $1, $3, @$); } | oper_expr INTERSECTION oper_expr - { $$ = make_shared<BinaryOp>(codes::BinaryOp::set_intersection, $1, $3, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::set_intersection, $1, $3, @$); } ; colon_expr : oper_expr COLON oper_expr - { $$ = make_shared<Range>($1, $3, driver.env, @$); } + { $$ = make_shared<Range>($1, $3, @$); } | oper_expr COLON oper_expr COLON oper_expr - { $$ = make_shared<Range>($1, $3, $5, driver.env, @$); } + { $$ = make_shared<Range>($1, $3, $5, @$); } ; expr : oper_expr | colon_expr | expr EQUAL_EQUAL expr - { $$ = make_shared<BinaryOp>(codes::BinaryOp::equal_equal, $1, $3, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::equal_equal, $1, $3, @$); } | expr NOT_EQUAL expr - { $$ = make_shared<BinaryOp>(codes::BinaryOp::not_equal, $1, $3, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::not_equal, $1, $3, @$); } | expr LESS expr - { $$ = make_shared<BinaryOp>(codes::BinaryOp::less, $1, $3, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::less, $1, $3, @$); } | expr GREATER expr - { $$ = make_shared<BinaryOp>(codes::BinaryOp::greater, $1, $3, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::greater, $1, $3, @$); } | expr LESS_EQUAL expr - { $$ = make_shared<BinaryOp>(codes::BinaryOp::less_equal, $1, $3, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::less_equal, $1, $3, @$); } | expr GREATER_EQUAL expr - { $$ = make_shared<BinaryOp>(codes::BinaryOp::greater_equal, $1, $3, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::greater_equal, $1, $3, @$); } | expr AND expr - { $$ = make_shared<BinaryOp>(codes::BinaryOp::logical_and, $1, $3, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::logical_and, $1, $3, @$); } | expr OR expr - { $$ = make_shared<BinaryOp>(codes::BinaryOp::logical_or, $1, $3, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::logical_or, $1, $3, @$); } | expr IN expr - { $$ = make_shared<BinaryOp>(codes::BinaryOp::in, $1, $3, driver.env, @$); } + { $$ = make_shared<BinaryOp>(codes::BinaryOp::in, $1, $3, @$); } ; %%