From 7e085855b3db619379f752eb313fd2cdf22e1c94 Mon Sep 17 00:00:00 2001 From: Houtan Bastani <houtan@dynare.org> Date: Fri, 2 Aug 2019 15:19:00 -0400 Subject: [PATCH] macro processor: introduce string casts --- src/macro/Expressions.cc | 8 ++++++++ src/macro/Expressions.hh | 6 ++++++ src/macro/ForwardDeclarationsAndEnums.hh | 1 + src/macro/Parser.yy | 6 ++++-- src/macro/Tokenizer.ll | 1 + 5 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/macro/Expressions.cc b/src/macro/Expressions.cc index 5e123148..f2121200 100644 --- a/src/macro/Expressions.cc +++ b/src/macro/Expressions.cc @@ -771,6 +771,8 @@ UnaryOp::eval() return argbt->cast_int(); case codes::UnaryOp::cast_double: return argbt->cast_double(); + case codes::UnaryOp::cast_string: + return argbt->cast_string(); case codes::UnaryOp::logical_not: return argbt->logical_not(); case codes::UnaryOp::unary_minus: @@ -1095,6 +1097,8 @@ UnaryOp::to_string() const noexcept return "(int)" + retval; case codes::UnaryOp::cast_double: return "(double)" + retval; + case codes::UnaryOp::cast_string: + return "(string)" + retval; case codes::UnaryOp::logical_not: return "!" + retval; case codes::UnaryOp::unary_minus: @@ -1301,6 +1305,9 @@ UnaryOp::print(ostream &output, bool matlab_output) const noexcept case codes::UnaryOp::cast_double: output << "(double)"; break; + case codes::UnaryOp::cast_string: + output << "(string)"; + break; case codes::UnaryOp::logical_not: output << "!"; break; @@ -1388,6 +1395,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::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 2e0b44d6..2dde31f4 100644 --- a/src/macro/Expressions.hh +++ b/src/macro/Expressions.hh @@ -182,6 +182,7 @@ namespace macro virtual DoublePtr normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const { throw StackTrace("Operator `normcdf` does not exist for this type"); } 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"); } }; @@ -206,6 +207,7 @@ namespace macro BoolPtr logical_not() const override; 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); } }; @@ -292,6 +294,7 @@ namespace macro DoublePtr normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const override; 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); } }; class String final : public BaseType @@ -318,6 +321,7 @@ namespace macro inline DoublePtr length() const override { return make_shared<Double>(value.size(), env); } inline DoublePtr cast_int() const override; inline DoublePtr cast_double() const override; + inline StringPtr cast_string() const override { return make_shared<String>(value, env); } }; @@ -345,6 +349,7 @@ namespace macro inline DoublePtr length() const override { return make_shared<Double>(tup.size(), env); } DoublePtr cast_int() const override; DoublePtr cast_double() const override; + inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); } }; @@ -388,6 +393,7 @@ namespace macro DoublePtr sum() const override; DoublePtr cast_int() const override; DoublePtr cast_double() const override; + inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); } }; diff --git a/src/macro/ForwardDeclarationsAndEnums.hh b/src/macro/ForwardDeclarationsAndEnums.hh index 98f10f0c..a0baa757 100644 --- a/src/macro/ForwardDeclarationsAndEnums.hh +++ b/src/macro/ForwardDeclarationsAndEnums.hh @@ -69,6 +69,7 @@ namespace macro { cast_int, cast_double, + cast_string, logical_not, unary_minus, unary_plus, diff --git a/src/macro/Parser.yy b/src/macro/Parser.yy index 1c850945..51d8384a 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 +%token INT DOUBLE STRING %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 +%precedence CAST_INT CAST_DOUBLE CAST_STRING %nonassoc POWER %token <string> NAME TEXT QUOTED_STRING NUMBER EOL @@ -326,6 +326,8 @@ expr : LPAREN expr RPAREN { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_int, $4, driver.env, @$); } | LPAREN DOUBLE RPAREN expr %prec CAST_DOUBLE { $$ = 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, @$); } | 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 7f499531..6f4b78d0 100644 --- a/src/macro/Tokenizer.ll +++ b/src/macro/Tokenizer.ll @@ -144,6 +144,7 @@ CONT \\\\{SPC}* <expr,eval>int { return token::INT; } <expr,eval>double { return token::DOUBLE; } +<expr,eval>string { return token::STRING; } <expr,eval>((([0-9]*\.[0-9]+)|([0-9]+\.))([ed][-+]?[0-9]+)?)|([0-9]+([ed][-+]?[0-9]+)?)|nan|inf { yylval->build<string>(yytext); -- GitLab