diff --git a/src/macro/Expressions.cc b/src/macro/Expressions.cc index f2121200799130b07b4b556de672dedd74ca82c9..696f4e33e37bc6c0e4ab7f8c2a8ff398b55f7880 100644 --- a/src/macro/Expressions.cc +++ b/src/macro/Expressions.cc @@ -773,6 +773,8 @@ UnaryOp::eval() return argbt->cast_double(); case codes::UnaryOp::cast_string: return argbt->cast_string(); + case codes::UnaryOp::cast_tuple: + return argbt->cast_tuple(); case codes::UnaryOp::logical_not: return argbt->logical_not(); case codes::UnaryOp::unary_minus: @@ -1099,6 +1101,8 @@ UnaryOp::to_string() const noexcept return "(double)" + retval; case codes::UnaryOp::cast_string: return "(string)" + retval; + case codes::UnaryOp::cast_tuple: + return "(tuple)" + retval; case codes::UnaryOp::logical_not: return "!" + retval; case codes::UnaryOp::unary_minus: @@ -1308,6 +1312,9 @@ UnaryOp::print(ostream &output, bool matlab_output) const noexcept case codes::UnaryOp::cast_string: output << "(string)"; break; + case codes::UnaryOp::cast_tuple: + output << "(tuple)"; + break; case codes::UnaryOp::logical_not: output << "!"; break; @@ -1396,6 +1403,7 @@ UnaryOp::print(ostream &output, bool matlab_output) const noexcept if (op_code != codes::UnaryOp::cast_int && op_code != codes::UnaryOp::cast_double && op_code != codes::UnaryOp::cast_string + && op_code != codes::UnaryOp::cast_tuple && op_code != codes::UnaryOp::logical_not && op_code != codes::UnaryOp::unary_plus && op_code != codes::UnaryOp::unary_minus) diff --git a/src/macro/Expressions.hh b/src/macro/Expressions.hh index 2dde31f4607f482b2aa6598ff2b8e3a0c183e414..61f2d4abe12be5c8e3c9c53719746f9ff8deb050 100644 --- a/src/macro/Expressions.hh +++ b/src/macro/Expressions.hh @@ -183,6 +183,7 @@ namespace macro virtual DoublePtr cast_int() const { throw StackTrace("This type cannot be cast to an integer"); } virtual DoublePtr cast_double() const { throw StackTrace("This type cannot be cast to a double"); } 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"); } }; @@ -208,6 +209,10 @@ namespace macro inline DoublePtr cast_int() const override { return value ? make_shared<Double>(1, env) : make_shared<Double>(0, env); } inline DoublePtr cast_double() const override { return cast_int(); } inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); } + inline TuplePtr cast_tuple() const override + { + return make_shared<Tuple>(vector<ExpressionPtr>{make_shared<Bool>(value, env)}, env); + } }; @@ -295,6 +300,10 @@ namespace macro inline DoublePtr cast_int() const override { return make_shared<Double>(static_cast<int>(value), env); } inline DoublePtr cast_double() const override { return make_shared<Double>(value, env); } inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); } + inline TuplePtr cast_tuple() const override + { + return make_shared<Tuple>(vector<ExpressionPtr>{make_shared<Double>(value, env)}, env); + } }; class String final : public BaseType @@ -322,6 +331,10 @@ namespace macro inline DoublePtr cast_int() const override; inline DoublePtr cast_double() const override; inline StringPtr cast_string() const override { return make_shared<String>(value, env); } + inline TuplePtr cast_tuple() const override + { + return make_shared<Tuple>(vector<ExpressionPtr>{make_shared<String>(value, env)}, env); + } }; @@ -350,6 +363,7 @@ namespace macro DoublePtr cast_int() const override; DoublePtr cast_double() 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); } }; @@ -394,6 +408,7 @@ namespace macro DoublePtr cast_int() const override; DoublePtr cast_double() 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); } }; diff --git a/src/macro/ForwardDeclarationsAndEnums.hh b/src/macro/ForwardDeclarationsAndEnums.hh index a0baa757a55474687d8ac4575b6456622891bca6..2fce6fe876e7ca71dea2346e734a37f3d4014bc4 100644 --- a/src/macro/ForwardDeclarationsAndEnums.hh +++ b/src/macro/ForwardDeclarationsAndEnums.hh @@ -70,6 +70,7 @@ namespace macro cast_int, cast_double, cast_string, + cast_tuple, logical_not, unary_minus, unary_plus, diff --git a/src/macro/Parser.yy b/src/macro/Parser.yy index 51d8384a9b7e4a642a66e530dc72f2fce8dcd3f9..12b46230c2dea305a3501daf6bce8a8822ed50ca 100644 --- a/src/macro/Parser.yy +++ b/src/macro/Parser.yy @@ -65,7 +65,7 @@ using namespace macro; %token SQRT CBRT SIGN MAX MIN FLOOR CEIL TRUNC SUM MOD %token ERF ERFC GAMMA LGAMMA ROUND NORMPDF NORMCDF LENGTH -%token INT DOUBLE STRING +%token INT DOUBLE STRING TUPLE %left OR %left AND @@ -78,7 +78,7 @@ using namespace macro; %left PLUS MINUS %left TIMES DIVIDE %precedence UMINUS UPLUS NOT -%precedence CAST_INT CAST_DOUBLE CAST_STRING +%precedence CAST_INT CAST_DOUBLE CAST_STRING CAST_TUPLE %nonassoc POWER %token <string> NAME TEXT QUOTED_STRING NUMBER EOL @@ -328,6 +328,8 @@ expr : LPAREN expr RPAREN { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_double, $4, driver.env, @$); } | LPAREN STRING RPAREN expr %prec CAST_STRING { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_string, $4, driver.env, @$); } + | LPAREN TUPLE RPAREN expr %prec CAST_TUPLE + { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_tuple, $4, driver.env, @$); } | NOT expr { $$ = make_shared<UnaryOp>(codes::UnaryOp::logical_not, $2, driver.env, @$); } | MINUS expr %prec UMINUS diff --git a/src/macro/Tokenizer.ll b/src/macro/Tokenizer.ll index 6f4b78d0a44f0bc4e625730aeb0290a31f47231e..e072e3cd27a76b5c3859d4178d4b66d7d93dec10 100644 --- a/src/macro/Tokenizer.ll +++ b/src/macro/Tokenizer.ll @@ -145,6 +145,7 @@ CONT \\\\{SPC}* <expr,eval>int { return token::INT; } <expr,eval>double { return token::DOUBLE; } <expr,eval>string { return token::STRING; } +<expr,eval>tuple { return token::TUPLE; } <expr,eval>((([0-9]*\.[0-9]+)|([0-9]+\.))([ed][-+]?[0-9]+)?)|([0-9]+([ed][-+]?[0-9]+)?)|nan|inf { yylval->build<string>(yytext);