Verified Commit a3e63101 authored by Houtan Bastani's avatar Houtan Bastani
Browse files

support `save` option of @#echomacrovars

parent f400f024
Pipeline #1433 passed with stage
in 1 minute and 54 seconds
......@@ -120,7 +120,7 @@ Echo::interpret(ostream &output, bool no_line_macro)
{
error(StackTrace("@#echo", e.what(), location));
}
printLineInfo(output, no_line_macro);
printEndLineInfo(output, no_line_macro);
}
void
......@@ -141,6 +141,16 @@ Error::interpret(ostream &output, bool no_line_macro)
}
}
void
EchoMacroVars::interpret(ostream &output, bool no_line_macro)
{
if (save)
env.print(output, location.begin.line, true);
else
env.print(cout);
printEndLineInfo(output, no_line_macro);
}
void
For::interpret(ostream &output, bool no_line_macro)
{
......
......@@ -137,9 +137,13 @@ namespace macro
class EchoMacroVars : public Directive
{
private:
bool save;
public:
EchoMacroVars(Environment &env_arg, const Tokenizer::location location_arg) : Directive(env_arg, move(location_arg)) { }
inline void interpret(ostream &output, bool no_line_macro) override { env.print(); }
EchoMacroVars(bool save_arg,
Environment &env_arg, const Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), save{save_arg} { }
void interpret(ostream &output, bool no_line_macro) override;
};
......
......@@ -101,32 +101,42 @@ Environment::isFunctionDefined(const string &name) const noexcept
}
void
Environment::print() const
Environment::print(ostream &output, int line, bool save) const
{
if (!variables.empty())
if (!save && !variables.empty())
output << "Macro Variables:" << endl;
for (auto & it : variables)
{
cout << "Macro Variables:" << endl;
for (auto & it : variables)
{
cout << " " << it.first << " = ";
getVariable(it.first)->eval()->print(cout);
cout << endl;
}
output << (save ? "options_.macrovars_line_" + to_string(line) + "." : " " );
output << it.first << " = ";
getVariable(it.first)->eval()->print(output, true);
if (save)
output << ";";
output << endl;
}
if (!functions.empty())
if (!save && !functions.empty())
output << "Macro Functions:" << endl;
for (auto & it : functions)
{
cout << "Macro Functions:" << endl;
for (auto & it : functions)
output << (save ? "options_.macrovars_line_" + to_string(line) + ".function." : " " );
if (save)
{
cout << " ";
get<0>(it.second)->print(cout);
cout << " = ";
get<1>(it.second)->print(cout);
cout << endl;
get<0>(it.second)->printName(output);
output << " = '";
}
get<0>(it.second)->print(output);
output << " = ";
get<1>(it.second)->print(output);
if (save)
output << "';";
output << endl;
}
if (parent)
parent->print();
parent->print(output, line, save);
}
......@@ -46,7 +46,7 @@ namespace macro
bool isVariableDefined(const string &name) const noexcept;
bool isFunctionDefined(const string &name) const noexcept;
inline bool isSymbolDefined(const string &name) const noexcept { return isVariableDefined(name) || isFunctionDefined(name); }
void print() const;
void print(ostream &output, int line = -1, bool save = false) const;
inline size_t size() const noexcept { return variables.size() + functions.size(); }
inline const Environment *getGlobalEnv() const noexcept { return parent == nullptr ? this : parent->getGlobalEnv(); }
};
......
......@@ -1094,35 +1094,43 @@ Comprehension::to_string() const noexcept
}
void
Array::print(ostream &output) const noexcept
String::print(ostream &output, bool matlab_output) const noexcept
{
output << "[";
output << (matlab_output ? "'" : R"(")");
output << value;
output << (matlab_output ? "'" : R"(")");
}
void
Array::print(ostream &output, bool matlab_output) const noexcept
{
output << (matlab_output ? "{" : "[");
for (auto it = arr.begin(); it != arr.end(); it++)
{
if (it != arr.begin())
output << ", ";
(*it)->print(output);
(*it)->print(output, matlab_output);
}
output << "]";
output << (matlab_output ? "}" : "]");
}
void
Tuple::print(ostream &output) const noexcept
Tuple::print(ostream &output, bool matlab_output) const noexcept
{
output << "(";
output << (matlab_output ? "{" : "(");
for (auto it = tup.begin(); it != tup.end(); it++)
{
if (it != tup.begin())
output << ", ";
(*it)->print(output);
(*it)->print(output, matlab_output);
}
output << ")";
output << (matlab_output ? "}" : ")");
}
void
Function::print(ostream &output) const noexcept
Function::printArgs(ostream &output) const noexcept
{
output << name << "(";
output << "(";
for (auto it = args.begin(); it != args.end(); it++)
{
if (it != args.begin())
......@@ -1133,7 +1141,7 @@ Function::print(ostream &output) const noexcept
}
void
UnaryOp::print(ostream &output) const noexcept
UnaryOp::print(ostream &output, bool matlab_output) const noexcept
{
switch (op_code)
{
......@@ -1220,7 +1228,7 @@ UnaryOp::print(ostream &output) const noexcept
break;
}
arg->print(output);
arg->print(output, matlab_output);
if (op_code != codes::UnaryOp::logical_not
&& op_code != codes::UnaryOp::unary_plus
......@@ -1229,7 +1237,7 @@ UnaryOp::print(ostream &output) const noexcept
}
void
BinaryOp::print(ostream &output) const noexcept
BinaryOp::print(ostream &output, bool matlab_output) const noexcept
{
if (op_code == codes::BinaryOp::set_union
|| op_code == codes::BinaryOp::set_intersection
......@@ -1257,14 +1265,14 @@ BinaryOp::print(ostream &output) const noexcept
default:
break;
}
arg1->print(output);
arg1->print(output, matlab_output);
output << ", ";
arg2->print(output);
arg2->print(output, matlab_output);
output << ")";
return;
}
arg1->print(output);
arg1->print(output, matlab_output);
switch(op_code)
{
case codes::BinaryOp::plus:
......@@ -1317,11 +1325,11 @@ BinaryOp::print(ostream &output) const noexcept
cerr << "macro::BinaryOp::print: Should not arrive here" << endl;
exit(EXIT_FAILURE);
}
arg2->print(output);
arg2->print(output, matlab_output);
}
void
TrinaryOp::print(ostream &output) const noexcept
TrinaryOp::print(ostream &output, bool matlab_output) const noexcept
{
switch(op_code)
{
......@@ -1332,23 +1340,23 @@ TrinaryOp::print(ostream &output) const noexcept
output << "normcdf(";
break;
}
arg1->print(output);
arg1->print(output, matlab_output);
output << ", ";
arg2->print(output);
arg2->print(output, matlab_output);
output << ", ";
arg3->print(output);
arg3->print(output, matlab_output);
output << ")";
}
void
Comprehension::print(ostream &output) const noexcept
Comprehension::print(ostream &output, bool matlab_output) const noexcept
{
output << "[";
c_vars->print(output);
c_vars->print(output, matlab_output);
output << " in ";
c_set->print(output);
c_set->print(output, matlab_output);
output << " when ";
c_when->print(output);
c_when->print(output, matlab_output);
output << "]";
}
......@@ -114,7 +114,7 @@ namespace macro
Expression(Environment &env_arg, const Tokenizer::location location_arg) :
Node(env_arg, move(location_arg)) { }
virtual string to_string() const noexcept = 0;
virtual void print(ostream &output) const noexcept = 0;
virtual void print(ostream &output, bool matlab_output = false) const noexcept = 0;
virtual BaseTypePtr eval() = 0;
};
......@@ -193,7 +193,7 @@ namespace macro
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) const noexcept override { output << to_string(); }
inline void print(ostream &output, bool matlab_output = false) const noexcept override { output << to_string(); }
public:
operator bool() const { return value; }
BoolPtr is_equal(const BaseTypePtr &btp) const override;
......@@ -225,7 +225,7 @@ namespace macro
strs << setprecision(15) << value;
return strs.str();
}
inline void print(ostream &output) const noexcept override { output << to_string(); }
inline void print(ostream &output, bool matlab_output = false) const noexcept override { output << to_string(); }
public:
operator double() const { return value; }
BaseTypePtr plus(const BaseTypePtr &bt) const override;
......@@ -287,7 +287,7 @@ namespace macro
value{move(value_arg)} { }
inline codes::BaseType getType() const noexcept override { return codes::BaseType::String; }
inline string to_string() const noexcept override { return value; }
inline void print(ostream &output) const noexcept override { output << R"(")" << value << R"(")"; }
void print(ostream &output, bool matlab_output = false) const noexcept override;
public:
operator string() const { return value; }
BaseTypePtr plus(const BaseTypePtr &bt) const override;
......@@ -311,7 +311,7 @@ namespace macro
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) const noexcept override;
void print(ostream &output, bool matlab_output = false) const noexcept override;
BaseTypePtr eval() override;
public:
inline size_t size() const { return tup.size(); }
......@@ -344,7 +344,7 @@ namespace macro
range1{move(range1_arg)}, increment{move(increment_arg)}, range2{move(range2_arg)} { }
inline codes::BaseType getType() const noexcept override { return codes::BaseType::Array; }
string to_string() const noexcept override;
void print(ostream &output) const noexcept override;
void print(ostream &output, bool matlab_output = false) const noexcept override;
BaseTypePtr eval() override;
private:
BaseTypePtr evalArray();
......@@ -382,7 +382,7 @@ namespace macro
indices = make_shared<Array>(vector<ExpressionPtr>{indices_arg}, env);
}
inline string to_string() const noexcept override { return name; }
inline void print(ostream &output) const noexcept override { output << name; }
inline void print(ostream &output, bool matlab_output = false) const noexcept override { output << name; }
BaseTypePtr eval() override;
public:
inline string getName() const noexcept { return name; }
......@@ -401,9 +401,11 @@ namespace macro
Environment &env_arg, const Tokenizer::location location_arg) :
Expression(env_arg, move(location_arg)), name{move(name_arg)}, args{move(args_arg)} { }
string to_string() const noexcept override;
void print(ostream &output) const noexcept override;
inline void print(ostream &output, bool matlab_output = false) const noexcept override { printName(output); printArgs(output); }
BaseTypePtr eval() override;
public:
inline void printName(ostream &output) const noexcept { output << name; }
void printArgs(ostream &output) const noexcept;
inline string getName() const { return name; }
inline vector<ExpressionPtr> getArgs() const { return args; }
};
......@@ -420,7 +422,7 @@ namespace macro
Environment &env_arg, const Tokenizer::location location_arg) :
Expression(env_arg, move(location_arg)), op_code{move(op_code_arg)}, arg{move(arg_arg)} { }
string to_string() const noexcept override;
void print(ostream &output) const noexcept override;
void print(ostream &output, bool matlab_output = false) const noexcept override;
BaseTypePtr eval() override;
};
......@@ -438,7 +440,7 @@ namespace macro
arg1{move(arg1_arg)}, arg2{move(arg2_arg)} { }
public:
string to_string() const noexcept override;
void print(ostream &output) const noexcept override;
void print(ostream &output, bool matlab_output = false) const noexcept override;
BaseTypePtr eval() override;
};
......@@ -455,7 +457,7 @@ namespace macro
Expression(env_arg, move(location_arg)), op_code{move(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) const noexcept override;
void print(ostream &output, bool matlab_output = false) const noexcept override;
BaseTypePtr eval() override;
};
......@@ -472,7 +474,7 @@ namespace macro
Expression(env_arg, 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) const noexcept override;
void print(ostream &output, bool matlab_output = false) const noexcept override;
BaseTypePtr eval() override;
};
}
......
......@@ -64,7 +64,7 @@ using namespace macro;
%token FOR ENDFOR IF IFDEF IFNDEF ELSE ENDIF TRUE FALSE
%token INCLUDE INCLUDEPATH DEFINE EQUAL D_ECHO ERROR
%token COMMA LPAREN RPAREN LBRACKET RBRACKET WHEN
%token BEGIN_EVAL END_EVAL ECHOMACROVARS
%token BEGIN_EVAL END_EVAL ECHOMACROVARS SAVE
%token EXP LOG LN LOG10 SIN COS TAN ASIN ACOS ATAN
%token SQRT CBRT SIGN MAX MIN FLOOR CEIL TRUNC SUM MOD
......@@ -137,7 +137,9 @@ directive_one_line : INCLUDE expr
| ERROR expr
{ $$ = make_shared<Error>($2, driver.env, @$); }
| ECHOMACROVARS
{ $$ = make_shared<EchoMacroVars>(driver.env, @$); }
{ $$ = make_shared<EchoMacroVars>(false, driver.env, @$); }
| ECHOMACROVARS LPAREN SAVE RPAREN
{ $$ = make_shared<EchoMacroVars>(true, driver.env, @$); }
;
directive_multiline : for
......
......@@ -81,7 +81,7 @@ CONT \\\\{SPC}*
<directive>endif { BEGIN(end_line); return token::ENDIF; }
<directive>for { BEGIN(expr); return token::FOR; }
<directive>endfor { BEGIN(end_line); return token::ENDFOR; }
<directive>echomacrovars { BEGIN(end_line); return token::ECHOMACROVARS; }
<directive>echomacrovars { BEGIN(expr); return token::ECHOMACROVARS; }
<expr,eval>\+ { return token::PLUS; }
<expr,eval>- { return token::MINUS; }
......@@ -112,6 +112,7 @@ CONT \\\\{SPC}*
<expr,eval>\] { return token::RBRACKET; }
<expr,eval>in { return token::IN; }
<expr,eval>when { return token::WHEN; }
<expr,eval>save { return token::SAVE; }
<expr,eval>true { return token::TRUE; }
<expr,eval>false { return token::FALSE; }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment