[flang] allow array constructors in all expressions
authorpeter klausler <pklausler@nvidia.com>
Tue, 30 Oct 2018 23:25:10 +0000 (16:25 -0700)
committerpeter klausler <pklausler@nvidia.com>
Thu, 8 Nov 2018 17:35:48 +0000 (09:35 -0800)
Original-commit: flang-compiler/f18@6dd5431cd9a0da203f098487a7d5db379c64b3ea
Reviewed-on: https://github.com/flang-compiler/f18/pull/225
Tree-same-pre-rewrite: false

flang/lib/evaluate/expression.cc
flang/lib/evaluate/expression.h
flang/lib/evaluate/type.h

index f6f39a1..059bdf3 100644 (file)
@@ -132,7 +132,7 @@ std::ostream &Emit(std::ostream &o, const ArrayConstructorValues<T> &values) {
 
 template<typename T>
 std::ostream &ArrayConstructor<T>::Dump(std::ostream &o) const {
-  o << '[' << Result::Dump() << "::";
+  o << '[' << result.Dump() << "::";
   Emit(o, *this);
   return o << ']';
 }
@@ -148,6 +148,11 @@ std::ostream &ExpressionBase<RESULT>::Dump(std::ostream &o) const {
   return o;
 }
 
+template<typename T> Expr<SubscriptInteger> ArrayConstructor<T>::LEN() const {
+  // TODO pmk: extract from type spec
+  return AsExpr(Constant<SubscriptInteger>{0});  // TODO placeholder
+}
+
 template<int KIND>
 Expr<SubscriptInteger> Expr<Type<TypeCategory::Character, KIND>>::LEN() const {
   return std::visit(
@@ -155,6 +160,7 @@ Expr<SubscriptInteger> Expr<Type<TypeCategory::Character, KIND>>::LEN() const {
                          return AsExpr(
                              Constant<SubscriptInteger>{c.value.size()});
                        },
+          [](const ArrayConstructor<Result> &a) { return a.LEN(); },
           [](const Parentheses<Result> &x) { return x.left().LEN(); },
           [](const Concat<KIND> &c) {
             return c.left().LEN() + c.right().LEN();
@@ -170,6 +176,11 @@ Expr<SubscriptInteger> Expr<Type<TypeCategory::Character, KIND>>::LEN() const {
 
 Expr<SomeType>::~Expr() {}
 
+template<typename T> DynamicType ArrayConstructor<T>::GetType() const {
+  // TODO: pmk: parameterized derived types, CHARACTER length
+  return *result.GetType();
+}
+
 template<typename A>
 std::optional<DynamicType> ExpressionBase<A>::GetType() const {
   if constexpr (Result::isSpecificIntrinsicType) {
index 37a4908..436617e 100644 (file)
@@ -413,7 +413,10 @@ template<typename RESULT>
 struct ArrayConstructor : public ArrayConstructorValues<RESULT> {
   using Result = RESULT;
   using ArrayConstructorValues<Result>::ArrayConstructorValues;
+  Result result;
+  DynamicType GetType() const;
   static constexpr int Rank() { return 1; }
+  Expr<SubscriptInteger> LEN() const;
   std::ostream &Dump(std::ostream &) const;
 };
 
@@ -463,8 +466,8 @@ private:
   using Operations = std::variant<ComplexComponent<KIND>, Parentheses<Result>,
       Negate<Result>, Add<Result>, Subtract<Result>, Multiply<Result>,
       Divide<Result>, Power<Result>, RealToIntPower<Result>, Extremum<Result>>;
-  using Others =
-      std::variant<Constant<Result>, Designator<Result>, FunctionRef<Result>>;
+  using Others = std::variant<Constant<Result>, ArrayConstructor<Result>,
+      Designator<Result>, FunctionRef<Result>>;
 
 public:
   common::CombineVariants<Operations, Conversions, Others> u;
@@ -483,8 +486,8 @@ public:
   using Operations =
       std::variant<Parentheses<Result>, Multiply<Result>, Divide<Result>,
           Power<Result>, RealToIntPower<Result>, ComplexConstructor<KIND>>;
-  using Others =
-      std::variant<Constant<Result>, Designator<Result>, FunctionRef<Result>>;
+  using Others = std::variant<Constant<Result>, ArrayConstructor<Result>,
+      Designator<Result>, FunctionRef<Result>>;
 
 public:
   common::CombineVariants<Operations, Others> u;
@@ -505,8 +508,8 @@ public:
 
   Expr<SubscriptInteger> LEN() const;
 
-  std::variant<Constant<Result>, Designator<Result>, FunctionRef<Result>,
-      Parentheses<Result>, Concat<KIND>, Extremum<Result>>
+  std::variant<Constant<Result>, ArrayConstructor<Result>, Designator<Result>,
+      FunctionRef<Result>, Parentheses<Result>, Concat<KIND>, Extremum<Result>>
       u;
 };
 
@@ -581,8 +584,8 @@ private:
       Parentheses<Result>, Not<KIND>, LogicalOperation<KIND>>;
   using Relations = std::conditional_t<KIND == LogicalResult::kind,
       std::variant<Relational<SomeType>>, std::variant<>>;
-  using Others =
-      std::variant<Constant<Result>, Designator<Result>, FunctionRef<Result>>;
+  using Others = std::variant<Constant<Result>, ArrayConstructor<Result>,
+      Designator<Result>, FunctionRef<Result>>;
 
 public:
   common::CombineVariants<Operations, Relations, Others> u;
@@ -590,6 +593,17 @@ public:
 
 FOR_EACH_LOGICAL_KIND(extern template class Expr)
 
+// An expression whose result has a derived type.
+template<> class Expr<SomeDerived> : public ExpressionBase<SomeDerived> {
+public:
+  using Result = SomeDerived;
+  EVALUATE_UNION_CLASS_BOILERPLATE(Expr)
+  // TODO: structure constructor
+  std::variant<Designator<Result>, ArrayConstructor<Result>,
+      FunctionRef<Result>>
+      u;
+};
+
 // A polymorphic expression of known intrinsic type category, but dynamic
 // kind, represented as a discriminated union over Expr<Type<CAT, K>>
 // for each supported kind K in the category.
@@ -601,15 +615,6 @@ public:
   common::MapTemplate<Expr, CategoryTypes<CAT>> u;
 };
 
-// An expression whose result has a derived type.
-template<> class Expr<SomeDerived> : public ExpressionBase<SomeDerived> {
-public:
-  using Result = SomeDerived;
-  EVALUATE_UNION_CLASS_BOILERPLATE(Expr)
-  // TODO: array constructor, structure constructor
-  std::variant<Designator<Result>, FunctionRef<Result>> u;
-};
-
 // A completely generic expression, polymorphic across all of the intrinsic type
 // categories and each of their kinds.
 template<> class Expr<SomeType> : public ExpressionBase<SomeType> {
index 00934cc..3357612 100644 (file)
@@ -322,7 +322,7 @@ struct SomeType {
 // and derived type constants are structure constructors; generic
 // constants are generic expressions wrapping these constants.
 template<typename T> struct Constant {
-  // TODO: static_assert(T::isSpecificIntrinsicType);
+  static_assert(T::isSpecificIntrinsicType);
   using Result = T;
   using Value = Scalar<Result>;
   CLASS_BOILERPLATE(Constant)