From a98e682d7b7bd29ab3c2526ee8be4b3cf9cffba1 Mon Sep 17 00:00:00 2001 From: peter klausler Date: Tue, 30 Oct 2018 15:24:35 -0700 Subject: [PATCH] [flang] represent array constructors 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 | 38 ++++++++++++++++++++++++++++++++++ flang/lib/evaluate/expression.h | 44 ++++++++++++++++++++++++++++++++++++++-- flang/lib/evaluate/type.cc | 10 +++++++++ flang/lib/evaluate/type.h | 7 +++---- 4 files changed, 93 insertions(+), 6 deletions(-) diff --git a/flang/lib/evaluate/expression.cc b/flang/lib/evaluate/expression.cc index c8380c4..f6f39a1 100644 --- a/flang/lib/evaluate/expression.cc +++ b/flang/lib/evaluate/expression.cc @@ -99,6 +99,44 @@ template std::ostream &Constant::Dump(std::ostream &o) const { } } +template +std::ostream &Emit(std::ostream &o, const CopyableIndirection> &expr) { + return expr->Dump(o); +} +template +std::ostream &Emit(std::ostream &, const ArrayConstructorValues &); + +template +std::ostream &Emit(std::ostream &o, const ImpliedDo &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 +std::ostream &Emit(std::ostream &o, const ArrayConstructorValues &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 +std::ostream &ArrayConstructor::Dump(std::ostream &o) const { + o << '[' << Result::Dump() << "::"; + Emit(o, *this); + return o << ']'; +} + template std::ostream &ExpressionBase::Dump(std::ostream &o) const { std::visit(common::visitors{[&](const BOZLiteralConstant &x) { diff --git a/flang/lib/evaluate/expression.h b/flang/lib/evaluate/expression.h index 8210b78d..37a4908 100644 --- a/flang/lib/evaluate/expression.h +++ b/flang/lib/evaluate/expression.h @@ -378,6 +378,45 @@ struct LogicalOperation LogicalOperator logicalOperator; }; +// Array constructors + +template struct ArrayConstructorValues; + +template struct ImpliedDo { + using Item = ITEM; + using Result = typename Item::Result; + using Operand = OPERAND; + static_assert(Operand::category == TypeCategory::Integer); + parser::CharBlock controlVariableName; + CopyableIndirection> lower, upper, stride; + CopyableIndirection values; +}; + +template struct ArrayConstructorValue { + using Result = RESULT; + EVALUATE_UNION_CLASS_BOILERPLATE(ArrayConstructorValue) + template + using ImpliedDo = ImpliedDo, INT>; + common::CombineVariants>>, + common::MapTemplate> + u; +}; + +template struct ArrayConstructorValues { + using Result = RESULT; + CLASS_BOILERPLATE(ArrayConstructorValues) + template void Push(A &&x) { values.emplace_back(std::move(x)); } + std::vector> values; +}; + +template +struct ArrayConstructor : public ArrayConstructorValues { + using Result = RESULT; + using ArrayConstructorValues::ArrayConstructorValues; + static constexpr int Rank() { return 1; } + std::ostream &Dump(std::ostream &) const; +}; + // Per-category expression representations template @@ -399,8 +438,8 @@ private: using Operations = std::variant, Negate, Add, Subtract, Multiply, Divide, Power, Extremum>; - using Others = - std::variant, Designator, FunctionRef>; + using Others = std::variant, ArrayConstructor, + Designator, FunctionRef>; public: common::CombineVariants u; @@ -567,6 +606,7 @@ template<> class Expr : public ExpressionBase { public: using Result = SomeDerived; EVALUATE_UNION_CLASS_BOILERPLATE(Expr) + // TODO: array constructor, structure constructor std::variant, FunctionRef> u; }; diff --git a/flang/lib/evaluate/type.cc b/flang/lib/evaluate/type.cc index ebe5a03..bb26628 100644 --- a/flang/lib/evaluate/type.cc +++ b/flang/lib/evaluate/type.cc @@ -46,6 +46,16 @@ std::optional 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: diff --git a/flang/lib/evaluate/type.h b/flang/lib/evaluate/type.h index 155d4b8..00934cc 100644 --- a/flang/lib/evaluate/type.h +++ b/flang/lib/evaluate/type.h @@ -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 GetSymbolType(const semantics::Symbol &); -- 2.7.4