[flang] allow array constructors in all expressions

Original-commit: flang-compiler/f18@6dd5431cd9
Reviewed-on: https://github.com/flang-compiler/f18/pull/225
Tree-same-pre-rewrite: false
This commit is contained in:
peter klausler 2018-10-30 16:25:10 -07:00
parent a98e682d7b
commit e364b3db8e
3 changed files with 35 additions and 19 deletions

View File

@ -132,7 +132,7 @@ std::ostream &Emit(std::ostream &o, const ArrayConstructorValues<T> &values) {
template<typename T> template<typename T>
std::ostream &ArrayConstructor<T>::Dump(std::ostream &o) const { std::ostream &ArrayConstructor<T>::Dump(std::ostream &o) const {
o << '[' << Result::Dump() << "::"; o << '[' << result.Dump() << "::";
Emit(o, *this); Emit(o, *this);
return o << ']'; return o << ']';
} }
@ -148,6 +148,11 @@ std::ostream &ExpressionBase<RESULT>::Dump(std::ostream &o) const {
return o; 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> template<int KIND>
Expr<SubscriptInteger> Expr<Type<TypeCategory::Character, KIND>>::LEN() const { Expr<SubscriptInteger> Expr<Type<TypeCategory::Character, KIND>>::LEN() const {
return std::visit( return std::visit(
@ -155,6 +160,7 @@ Expr<SubscriptInteger> Expr<Type<TypeCategory::Character, KIND>>::LEN() const {
return AsExpr( return AsExpr(
Constant<SubscriptInteger>{c.value.size()}); Constant<SubscriptInteger>{c.value.size()});
}, },
[](const ArrayConstructor<Result> &a) { return a.LEN(); },
[](const Parentheses<Result> &x) { return x.left().LEN(); }, [](const Parentheses<Result> &x) { return x.left().LEN(); },
[](const Concat<KIND> &c) { [](const Concat<KIND> &c) {
return c.left().LEN() + c.right().LEN(); return c.left().LEN() + c.right().LEN();
@ -170,6 +176,11 @@ Expr<SubscriptInteger> Expr<Type<TypeCategory::Character, KIND>>::LEN() const {
Expr<SomeType>::~Expr() {} Expr<SomeType>::~Expr() {}
template<typename T> DynamicType ArrayConstructor<T>::GetType() const {
// TODO: pmk: parameterized derived types, CHARACTER length
return *result.GetType();
}
template<typename A> template<typename A>
std::optional<DynamicType> ExpressionBase<A>::GetType() const { std::optional<DynamicType> ExpressionBase<A>::GetType() const {
if constexpr (Result::isSpecificIntrinsicType) { if constexpr (Result::isSpecificIntrinsicType) {

View File

@ -413,7 +413,10 @@ template<typename RESULT>
struct ArrayConstructor : public ArrayConstructorValues<RESULT> { struct ArrayConstructor : public ArrayConstructorValues<RESULT> {
using Result = RESULT; using Result = RESULT;
using ArrayConstructorValues<Result>::ArrayConstructorValues; using ArrayConstructorValues<Result>::ArrayConstructorValues;
Result result;
DynamicType GetType() const;
static constexpr int Rank() { return 1; } static constexpr int Rank() { return 1; }
Expr<SubscriptInteger> LEN() const;
std::ostream &Dump(std::ostream &) const; std::ostream &Dump(std::ostream &) const;
}; };
@ -463,8 +466,8 @@ private:
using Operations = std::variant<ComplexComponent<KIND>, Parentheses<Result>, using Operations = std::variant<ComplexComponent<KIND>, Parentheses<Result>,
Negate<Result>, Add<Result>, Subtract<Result>, Multiply<Result>, Negate<Result>, Add<Result>, Subtract<Result>, Multiply<Result>,
Divide<Result>, Power<Result>, RealToIntPower<Result>, Extremum<Result>>; Divide<Result>, Power<Result>, RealToIntPower<Result>, Extremum<Result>>;
using Others = using Others = std::variant<Constant<Result>, ArrayConstructor<Result>,
std::variant<Constant<Result>, Designator<Result>, FunctionRef<Result>>; Designator<Result>, FunctionRef<Result>>;
public: public:
common::CombineVariants<Operations, Conversions, Others> u; common::CombineVariants<Operations, Conversions, Others> u;
@ -483,8 +486,8 @@ public:
using Operations = using Operations =
std::variant<Parentheses<Result>, Multiply<Result>, Divide<Result>, std::variant<Parentheses<Result>, Multiply<Result>, Divide<Result>,
Power<Result>, RealToIntPower<Result>, ComplexConstructor<KIND>>; Power<Result>, RealToIntPower<Result>, ComplexConstructor<KIND>>;
using Others = using Others = std::variant<Constant<Result>, ArrayConstructor<Result>,
std::variant<Constant<Result>, Designator<Result>, FunctionRef<Result>>; Designator<Result>, FunctionRef<Result>>;
public: public:
common::CombineVariants<Operations, Others> u; common::CombineVariants<Operations, Others> u;
@ -505,8 +508,8 @@ public:
Expr<SubscriptInteger> LEN() const; Expr<SubscriptInteger> LEN() const;
std::variant<Constant<Result>, Designator<Result>, FunctionRef<Result>, std::variant<Constant<Result>, ArrayConstructor<Result>, Designator<Result>,
Parentheses<Result>, Concat<KIND>, Extremum<Result>> FunctionRef<Result>, Parentheses<Result>, Concat<KIND>, Extremum<Result>>
u; u;
}; };
@ -581,8 +584,8 @@ private:
Parentheses<Result>, Not<KIND>, LogicalOperation<KIND>>; Parentheses<Result>, Not<KIND>, LogicalOperation<KIND>>;
using Relations = std::conditional_t<KIND == LogicalResult::kind, using Relations = std::conditional_t<KIND == LogicalResult::kind,
std::variant<Relational<SomeType>>, std::variant<>>; std::variant<Relational<SomeType>>, std::variant<>>;
using Others = using Others = std::variant<Constant<Result>, ArrayConstructor<Result>,
std::variant<Constant<Result>, Designator<Result>, FunctionRef<Result>>; Designator<Result>, FunctionRef<Result>>;
public: public:
common::CombineVariants<Operations, Relations, Others> u; common::CombineVariants<Operations, Relations, Others> u;
@ -590,6 +593,17 @@ public:
FOR_EACH_LOGICAL_KIND(extern template class Expr) 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 // A polymorphic expression of known intrinsic type category, but dynamic
// kind, represented as a discriminated union over Expr<Type<CAT, K>> // kind, represented as a discriminated union over Expr<Type<CAT, K>>
// for each supported kind K in the category. // for each supported kind K in the category.
@ -601,15 +615,6 @@ public:
common::MapTemplate<Expr, CategoryTypes<CAT>> u; 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 // A completely generic expression, polymorphic across all of the intrinsic type
// categories and each of their kinds. // categories and each of their kinds.
template<> class Expr<SomeType> : public ExpressionBase<SomeType> { template<> class Expr<SomeType> : public ExpressionBase<SomeType> {

View File

@ -322,7 +322,7 @@ struct SomeType {
// and derived type constants are structure constructors; generic // and derived type constants are structure constructors; generic
// constants are generic expressions wrapping these constants. // constants are generic expressions wrapping these constants.
template<typename T> struct Constant { template<typename T> struct Constant {
// TODO: static_assert(T::isSpecificIntrinsicType); static_assert(T::isSpecificIntrinsicType);
using Result = T; using Result = T;
using Value = Scalar<Result>; using Value = Scalar<Result>;
CLASS_BOILERPLATE(Constant) CLASS_BOILERPLATE(Constant)