diff --git a/src/macro/Expressions.cc b/src/macro/Expressions.cc index 17dd4ad41fa9edda3fb91f94662c6bbfc074cc6f..692a0484ec7318a8dcb3c5ff87be7694d0c45062 100644 --- a/src/macro/Expressions.cc +++ b/src/macro/Expressions.cc @@ -948,6 +948,12 @@ Comprehension::eval() return make_shared<Array>(values, env); } +BaseTypePtr +ArrayComprehension::eval() +{ + return make_shared<Double>(1, env); +} + string Array::to_string() const noexcept { @@ -1117,6 +1123,15 @@ TrinaryOp::to_string() const noexcept exit(EXIT_FAILURE); } +string +ArrayComprehension::to_string() const noexcept +{ + string retval = "[" + c_expr->to_string() + " for " + c_vars->to_string() + " in " + c_set->to_string(); + if (c_when) + retval += " when " + c_when->to_string(); + return retval + "]"; +} + void String::print(ostream &output, bool matlab_output) const noexcept { @@ -1384,3 +1399,20 @@ Comprehension::print(ostream &output, bool matlab_output) const noexcept output << "]"; } +void +ArrayComprehension::print(ostream &output, bool matlab_output) const noexcept +{ + output << "["; + c_expr->print(output, matlab_output); + output << " for "; + c_vars->print(output, matlab_output); + output << " in "; + c_set->print(output, matlab_output); + if (c_when) + { + output << " when "; + c_when->print(output, matlab_output); + } + output << "]"; +} + diff --git a/src/macro/Expressions.hh b/src/macro/Expressions.hh index ef1ee74da5263e55d88576ba245df0ac025721a1..4cfaf51498b1aac9ecc7821cf6ff05a04706181c 100644 --- a/src/macro/Expressions.hh +++ b/src/macro/Expressions.hh @@ -472,5 +472,30 @@ namespace macro void print(ostream &output, bool matlab_output = false) const noexcept override; BaseTypePtr eval() override; }; + + + class ArrayComprehension final : public Expression + { + private: + const ExpressionPtr c_expr, c_vars, c_set, c_when; + public: + ArrayComprehension(const ExpressionPtr c_expr_arg, + const ExpressionPtr c_vars_arg, + const ExpressionPtr c_set_arg, + const ExpressionPtr c_when_arg, + Environment &env_arg, const Tokenizer::location location_arg) : + Expression(env_arg, 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)} { } + ArrayComprehension(const ExpressionPtr c_expr_arg, + const ExpressionPtr c_vars_arg, + const ExpressionPtr c_set_arg, + Environment &env_arg, const Tokenizer::location location_arg) : + Expression(env_arg, move(location_arg)), + c_expr{move(c_expr_arg)}, c_vars{move(c_vars_arg)}, c_set{move(c_set_arg)} { } + string to_string() const noexcept override; + void print(ostream &output, bool matlab_output = false) const noexcept override; + BaseTypePtr eval() override; + }; } #endif diff --git a/src/macro/Parser.yy b/src/macro/Parser.yy index 85972412fd4e8e055cf7d7248e9dc89363c76368..3c0060a17f181f58a743fa329832e8170d9148db 100644 --- a/src/macro/Parser.yy +++ b/src/macro/Parser.yy @@ -305,6 +305,10 @@ expr : LPAREN expr RPAREN { $$ = make_shared<Tuple>($2, driver.env, @$); } | LBRACKET expr IN expr WHEN expr RBRACKET { $$ = make_shared<Comprehension>($2, $4, $6, driver.env, @$); } + | LBRACKET expr FOR expr IN expr RBRACKET + { $$ = make_shared<ArrayComprehension>($2, $4, $6, driver.env, @$); } + | LBRACKET expr FOR expr IN expr WHEN expr RBRACKET + { $$ = make_shared<ArrayComprehension>($2, $4, $6, $8, driver.env, @$); } | NOT expr { $$ = make_shared<UnaryOp>(codes::UnaryOp::logical_not, $2, driver.env, @$); } | MINUS expr %prec UMINUS