[flang] represent array constructors
Original-commit: flang-compiler/f18@74ccff6b39 Reviewed-on: https://github.com/flang-compiler/f18/pull/225 Tree-same-pre-rewrite: false
This commit is contained in:
parent
72fd06b389
commit
a98e682d7b
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 &);
|
||||
|
|
Loading…
Reference in New Issue