[flang] represent array constructors
authorpeter klausler <pklausler@nvidia.com>
Tue, 30 Oct 2018 22:24:35 +0000 (15:24 -0700)
committerpeter klausler <pklausler@nvidia.com>
Thu, 8 Nov 2018 17:35:47 +0000 (09:35 -0800)
Original-commit: flang-compiler/f18@74ccff6b39972ada3d344ae8ee72d4c18842d35c
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.cc
flang/lib/evaluate/type.h

index c8380c4..f6f39a1 100644 (file)
@@ -99,6 +99,44 @@ template<typename T> std::ostream &Constant<T>::Dump(std::ostream &o) const {
   }
 }
 
+template<typename T>
+std::ostream &Emit(std::ostream &o, const CopyableIndirection<Expr<T>> &expr) {
+  return expr->Dump(o);
+}
+template<typename T>
+std::ostream &Emit(std::ostream &, const ArrayConstructorValues<T> &);
+
+template<typename ITEM, typename INT>
+std::ostream &Emit(std::ostream &o, const ImpliedDo<ITEM, INT> &implDo) {
+  o << '(';
+  Emit(o, *implDo.values);
+  o << ',' << INT::Dump() << "::";
+  o << implDo.controlVariableName.ToString();
+  o << '=';
+  implDo.lower->Dump(o) << ',';
+  implDo.upper->Dump(o) << ',';
+  implDo.stride->Dump(o) << ')';
+  return o;
+}
+
+template<typename T>
+std::ostream &Emit(std::ostream &o, const ArrayConstructorValues<T> &values) {
+  const char *sep{""};
+  for (const auto &value : values.values) {
+    o << sep;
+    std::visit([&](const auto &x) { Emit(o, x); }, value.u);
+    sep = ",";
+  }
+  return o;
+}
+
+template<typename T>
+std::ostream &ArrayConstructor<T>::Dump(std::ostream &o) const {
+  o << '[' << Result::Dump() << "::";
+  Emit(o, *this);
+  return o << ']';
+}
+
 template<typename RESULT>
 std::ostream &ExpressionBase<RESULT>::Dump(std::ostream &o) const {
   std::visit(common::visitors{[&](const BOZLiteralConstant &x) {
index 8210b78..37a4908 100644 (file)
@@ -378,6 +378,45 @@ struct LogicalOperation
   LogicalOperator logicalOperator;
 };
 
+// Array constructors
+
+template<typename RESULT> struct ArrayConstructorValues;
+
+template<typename ITEM, typename OPERAND> struct ImpliedDo {
+  using Item = ITEM;
+  using Result = typename Item::Result;
+  using Operand = OPERAND;
+  static_assert(Operand::category == TypeCategory::Integer);
+  parser::CharBlock controlVariableName;
+  CopyableIndirection<Expr<Operand>> lower, upper, stride;
+  CopyableIndirection<Item> values;
+};
+
+template<typename RESULT> struct ArrayConstructorValue {
+  using Result = RESULT;
+  EVALUATE_UNION_CLASS_BOILERPLATE(ArrayConstructorValue)
+  template<typename INT>
+  using ImpliedDo = ImpliedDo<ArrayConstructorValues<Result>, INT>;
+  common::CombineVariants<std::variant<CopyableIndirection<Expr<Result>>>,
+      common::MapTemplate<ImpliedDo, IntegerTypes>>
+      u;
+};
+
+template<typename RESULT> struct ArrayConstructorValues {
+  using Result = RESULT;
+  CLASS_BOILERPLATE(ArrayConstructorValues)
+  template<typename A> void Push(A &&x) { values.emplace_back(std::move(x)); }
+  std::vector<ArrayConstructorValue<Result>> values;
+};
+
+template<typename RESULT>
+struct ArrayConstructor : public ArrayConstructorValues<RESULT> {
+  using Result = RESULT;
+  using ArrayConstructorValues<Result>::ArrayConstructorValues;
+  static constexpr int Rank() { return 1; }
+  std::ostream &Dump(std::ostream &) const;
+};
+
 // Per-category expression representations
 
 template<int KIND>
@@ -399,8 +438,8 @@ private:
   using Operations = std::variant<Parentheses<Result>, Negate<Result>,
       Add<Result>, Subtract<Result>, Multiply<Result>, Divide<Result>,
       Power<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;
@@ -567,6 +606,7 @@ 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;
 };
 
index ebe5a03..bb26628 100644 (file)
@@ -46,6 +46,16 @@ std::optional<DynamicType> GetSymbolType(const semantics::Symbol &symbol) {
   return std::nullopt;
 }
 
+std::string DynamicType::Dump() const {
+  if (category == TypeCategory::Derived) {
+    // TODO: derived type parameters
+    return "TYPE("s + derived->name().ToString() + ')';
+  } else {
+    // TODO: CHARACTER length
+    return EnumToString(category) + '(' + std::to_string(kind) + ')';
+  }
+}
+
 DynamicType DynamicType::ResultTypeForMultiply(const DynamicType &that) const {
   switch (category) {
   case TypeCategory::Integer:
index 155d4b8..00934cc 100644 (file)
@@ -49,15 +49,14 @@ struct DynamicType {
     return category == that.category && kind == that.kind &&
         derived == that.derived;
   }
-  std::string Dump() const {
-    return EnumToString(category) + '(' + std::to_string(kind) + ')';
-  }
-
+  std::string Dump() const;
   DynamicType ResultTypeForMultiply(const DynamicType &) const;
 
   TypeCategory category;
   int kind{0};
   const semantics::DerivedTypeSpec *derived{nullptr};
+  // TODO pmk: descriptor for character length
+  // TODO pmk: derived type kind parameters and descriptor for lengths
 };
 
 std::optional<DynamicType> GetSymbolType(const semantics::Symbol &);