Macro-processor: move environment out of node classes
This completes the separation of parse trees from their evaluation. Closes: #32issue#70
parent
638b4c7ac5
commit
ec779235ea
|
@ -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())
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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, @$); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
|
Loading…
Reference in New Issue