From eaa8b8fa84d6cf5723a2677bb9b24c7147aa3552 Mon Sep 17 00:00:00 2001
From: Houtan Bastani <houtan@dynare.org>
Date: Fri, 2 Aug 2019 17:00:23 -0400
Subject: [PATCH] macro processor: introduce array casts

---
 src/macro/Expressions.cc                 |  8 ++++++++
 src/macro/Expressions.hh                 | 15 +++++++++++++++
 src/macro/ForwardDeclarationsAndEnums.hh |  1 +
 src/macro/Parser.yy                      |  6 ++++--
 src/macro/Tokenizer.ll                   |  1 +
 5 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/src/macro/Expressions.cc b/src/macro/Expressions.cc
index 696f4e33..d1a55187 100644
--- a/src/macro/Expressions.cc
+++ b/src/macro/Expressions.cc
@@ -775,6 +775,8 @@ UnaryOp::eval()
           return argbt->cast_string();
         case codes::UnaryOp::cast_tuple:
           return argbt->cast_tuple();
+        case codes::UnaryOp::cast_array:
+          return argbt->cast_array();
         case codes::UnaryOp::logical_not:
           return argbt->logical_not();
         case codes::UnaryOp::unary_minus:
@@ -1103,6 +1105,8 @@ UnaryOp::to_string() const noexcept
       return "(string)" + retval;
     case codes::UnaryOp::cast_tuple:
       return "(tuple)" + retval;
+    case codes::UnaryOp::cast_array:
+      return "(array)" + retval;
     case codes::UnaryOp::logical_not:
       return "!" + retval;
     case codes::UnaryOp::unary_minus:
@@ -1315,6 +1319,9 @@ UnaryOp::print(ostream &output, bool matlab_output) const noexcept
     case codes::UnaryOp::cast_tuple:
       output << "(tuple)";
       break;
+    case codes::UnaryOp::cast_array:
+      output << "(array)";
+      break;
     case codes::UnaryOp::logical_not:
       output << "!";
       break;
@@ -1404,6 +1411,7 @@ UnaryOp::print(ostream &output, bool matlab_output) const noexcept
       && op_code != codes::UnaryOp::cast_double
       && op_code != codes::UnaryOp::cast_string
       && op_code != codes::UnaryOp::cast_tuple
+      && op_code != codes::UnaryOp::cast_array
       && 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 61f2d4ab..d195ac15 100644
--- a/src/macro/Expressions.hh
+++ b/src/macro/Expressions.hh
@@ -184,6 +184,7 @@ namespace macro
     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"); }
+    virtual ArrayPtr cast_array() const { throw StackTrace("This type cannot be cast to an array"); }
   };
 
 
@@ -213,6 +214,10 @@ namespace macro
     {
       return make_shared<Tuple>(vector<ExpressionPtr>{make_shared<Bool>(value, env)}, env);
     }
+    inline ArrayPtr cast_array() const override
+    {
+      return make_shared<Array>(vector<ExpressionPtr>{make_shared<Bool>(value, env)}, env);
+    }
   };
 
 
@@ -304,6 +309,10 @@ namespace macro
     {
       return make_shared<Tuple>(vector<ExpressionPtr>{make_shared<Double>(value, env)}, env);
     }
+    inline ArrayPtr cast_array() const override
+    {
+      return make_shared<Array>(vector<ExpressionPtr>{make_shared<Double>(value, env)}, env);
+    }
   };
 
   class String final : public BaseType
@@ -335,6 +344,10 @@ namespace macro
     {
       return make_shared<Tuple>(vector<ExpressionPtr>{make_shared<String>(value, env)}, env);
     }
+    inline ArrayPtr cast_array() const override
+    {
+      return make_shared<Array>(vector<ExpressionPtr>{make_shared<String>(value, env)}, env);
+    }
   };
 
 
@@ -364,6 +377,7 @@ namespace macro
     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); }
+    inline ArrayPtr cast_array() const override { return make_shared<Array>(tup, env); }
   };
 
 
@@ -409,6 +423,7 @@ namespace macro
     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); }
+    inline ArrayPtr cast_array() const override { return make_shared<Array>(arr, env); }
   };
 
 
diff --git a/src/macro/ForwardDeclarationsAndEnums.hh b/src/macro/ForwardDeclarationsAndEnums.hh
index 2fce6fe8..78070e8d 100644
--- a/src/macro/ForwardDeclarationsAndEnums.hh
+++ b/src/macro/ForwardDeclarationsAndEnums.hh
@@ -71,6 +71,7 @@ namespace macro
        cast_double,
        cast_string,
        cast_tuple,
+       cast_array,
        logical_not,
        unary_minus,
        unary_plus,
diff --git a/src/macro/Parser.yy b/src/macro/Parser.yy
index 12b46230..7940dcfa 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 TUPLE
+%token INT DOUBLE STRING TUPLE ARRAY
 
 %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 CAST_TUPLE
+%precedence CAST_INT CAST_DOUBLE CAST_STRING CAST_TUPLE CAST_ARRAY
 %nonassoc POWER
 
 %token <string> NAME TEXT QUOTED_STRING NUMBER EOL
@@ -330,6 +330,8 @@ expr : LPAREN expr RPAREN
        { $$ = 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, @$); }
+     | LPAREN ARRAY RPAREN expr %prec CAST_ARRAY
+       { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_array, $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 e072e3cd..dfb15c0f 100644
--- a/src/macro/Tokenizer.ll
+++ b/src/macro/Tokenizer.ll
@@ -146,6 +146,7 @@ CONT \\\\{SPC}*
 <expr,eval>double          { return token::DOUBLE; }
 <expr,eval>string          { return token::STRING; }
 <expr,eval>tuple           { return token::TUPLE; }
+<expr,eval>array           { return token::ARRAY; }
 
 <expr,eval>((([0-9]*\.[0-9]+)|([0-9]+\.))([ed][-+]?[0-9]+)?)|([0-9]+([ed][-+]?[0-9]+)?)|nan|inf {
   yylval->build<string>(yytext);
-- 
GitLab