return Emit(o, u);
}
+template<typename T> std::ostream &Designator<T>::Dump(std::ostream &o) const {
+ std::visit(
+ common::visitors{[&](const Symbol *sym) { o << sym->name().ToString(); },
+ [&](const auto &x) { x.Dump(o); }},
+ u);
+ return o;
+}
+
// LEN()
static Expr<SubscriptInteger> SymbolLEN(const Symbol &sym) {
return AsExpr(Constant<SubscriptInteger>{0}); // TODO
Extremum<SubscriptInteger>{AsExpr(Constant<SubscriptInteger>{0}),
last() - first() + AsExpr(Constant<SubscriptInteger>{1})});
}
-template<typename A> Expr<SubscriptInteger> Designator<A>::LEN() const {
- return std::visit(
- common::visitors{[](const Symbol *s) { return SymbolLEN(*s); },
- [](const Component &c) { return c.LEN(); },
- [](const auto &x) { return x.LEN(); }},
- u);
+template<typename T> Expr<SubscriptInteger> Designator<T>::LEN() const {
+ if constexpr (Result::category == TypeCategory::Character) {
+ return std::visit(
+ common::visitors{[](const Symbol *s) { return SymbolLEN(*s); },
+ [](const Component &c) { return c.LEN(); },
+ [](const auto &x) { return x.LEN(); }},
+ u);
+ } else {
+ CHECK(!"LEN() on non-character Designator");
+ return AsExpr(Constant<SubscriptInteger>{0});
+ }
}
Expr<SubscriptInteger> ProcedureDesignator::LEN() const {
return std::visit(
u_);
}
int ComplexPart::Rank() const { return complex_.Rank(); }
+template<typename T> int Designator<T>::Rank() const {
+ return std::visit(
+ common::visitors{[](const Symbol *sym) { return sym->Rank(); },
+ [](const auto &x) { return x.Rank(); }},
+ u);
+}
int ProcedureDesignator::Rank() const {
if (const Symbol * symbol{GetSymbol()}) {
return symbol->Rank();
return 0;
}
-// GetSymbol
-const Symbol *Component::GetSymbol(bool first) const {
- return base_->GetSymbol(first);
+// GetFirstSymbol(), GetLastSymbol()
+const Symbol *Component::GetFirstSymbol() const {
+ return base_->GetFirstSymbol();
}
-const Symbol *ArrayRef::GetSymbol(bool first) const {
+const Symbol *Component::GetLastSymbol() const {
+ return base_->GetLastSymbol();
+}
+const Symbol *ArrayRef::GetFirstSymbol() const {
return std::visit(common::visitors{[](const Symbol *sym) { return sym; },
[=](const Component &component) {
- return component.GetSymbol(first);
+ return component.GetFirstSymbol();
}},
u);
}
-const Symbol *DataRef::GetSymbol(bool first) const {
+const Symbol *ArrayRef::GetLastSymbol() const {
return std::visit(common::visitors{[](const Symbol *sym) { return sym; },
- [=](const auto &x) { return x.GetSymbol(first); }},
+ [=](const Component &component) {
+ return component.GetLastSymbol();
+ }},
u);
}
-const Symbol *Substring::GetSymbol(bool first) const {
+const Symbol *DataRef::GetFirstSymbol() const {
+ return std::visit(common::visitors{[](const Symbol *sym) { return sym; },
+ [=](const auto &x) { return x.GetFirstSymbol(); }},
+ u);
+}
+const Symbol *DataRef::GetLastSymbol() const {
+ return std::visit(common::visitors{[](const Symbol *sym) { return sym; },
+ [=](const auto &x) { return x.GetLastSymbol(); }},
+ u);
+}
+const Symbol *Substring::GetFirstSymbol() const {
+ if (const DataRef * dataRef{std::get_if<DataRef>(&u_)}) {
+ return dataRef->GetFirstSymbol();
+ } else {
+ return nullptr; // substring of character literal
+ }
+}
+const Symbol *Substring::GetLastSymbol() const {
if (const DataRef * dataRef{std::get_if<DataRef>(&u_)}) {
- return dataRef->GetSymbol(first);
+ return dataRef->GetLastSymbol();
} else {
return nullptr; // substring of character literal
}
}
+template<typename T> const Symbol *Designator<T>::GetFirstSymbol() const {
+ return std::visit(common::visitors{[](const Symbol *sym) { return sym; },
+ [=](const auto &x) { return x.GetFirstSymbol(); }},
+ u);
+}
+template<typename T> const Symbol *Designator<T>::GetLastSymbol() const {
+ return std::visit(common::visitors{[](const Symbol *sym) { return sym; },
+ [=](const auto &x) { return x.GetLastSymbol(); }},
+ u);
+}
const Symbol *ProcedureDesignator::GetSymbol() const {
return std::visit(common::visitors{[](const Symbol *sym) { return sym; },
- [](const Component &c) { return c.GetSymbol(false); },
+ [](const Component &c) { return c.GetLastSymbol(); },
[](const auto &) -> const Symbol * { return nullptr; }},
u);
}
+template<typename T> std::optional<DynamicType> Designator<T>::GetType() const {
+ if constexpr (std::is_same_v<Result, SomeDerived>) {
+ if (const Symbol * sym{GetLastSymbol()}) {
+ return GetSymbolType(*sym);
+ } else {
+ return std::nullopt;
+ }
+ } else {
+ return Result::GetType();
+ }
+}
std::optional<DynamicType> ProcedureDesignator::GetType() const {
if (const Symbol * symbol{GetSymbol()}) {
return {GetSymbolType(*symbol)};
return std::nullopt;
}
-FOR_EACH_CHARACTER_KIND(template class Designator)
+FOR_EACH_SPECIFIC_TYPE(template class Designator)
}
DataRef &base() { return *base_; }
const Symbol &symbol() const { return *symbol_; }
int Rank() const;
- const Symbol *GetSymbol(bool first) const;
+ const Symbol *GetFirstSymbol() const;
+ const Symbol *GetLastSymbol() const;
Expr<SubscriptInteger> LEN() const;
std::ostream &Dump(std::ostream &) const;
: u{std::move(c)}, subscript(std::move(ss)) {}
int Rank() const;
- const Symbol *GetSymbol(bool first) const;
+ const Symbol *GetFirstSymbol() const;
+ const Symbol *GetLastSymbol() const;
Expr<SubscriptInteger> LEN() const;
std::ostream &Dump(std::ostream &) const;
CoarrayRef &set_team(Expr<SomeInteger> &&, bool isTeamNumber = false);
int Rank() const;
- const Symbol *GetSymbol(bool first) const {
- if (first) {
- return base_.front();
- } else {
- return base_.back();
- }
- }
+ const Symbol *GetFirstSymbol() const { return base_.front(); }
+ const Symbol *GetLastSymbol() const { return base_.back(); }
Expr<SubscriptInteger> LEN() const;
std::ostream &Dump(std::ostream &) const;
explicit DataRef(const Symbol &n) : u{&n} {}
int Rank() const;
- const Symbol *GetSymbol(bool first) const;
+ const Symbol *GetFirstSymbol() const;
+ const Symbol *GetLastSymbol() const;
Expr<SubscriptInteger> LEN() const;
std::ostream &Dump(std::ostream &) const;
Expr<SubscriptInteger> first() const;
Expr<SubscriptInteger> last() const;
int Rank() const;
- const Symbol *GetSymbol(bool first) const;
+ const Symbol *GetFirstSymbol() const;
+ const Symbol *GetLastSymbol() const;
Expr<SubscriptInteger> LEN() const;
std::optional<Strings> Fold(FoldingContext &);
std::ostream &Dump(std::ostream &) const;
const DataRef &complex() const { return complex_; }
Part part() const { return part_; }
int Rank() const;
- const Symbol *GetSymbol(bool first) const {
- return complex_.GetSymbol(first);
- }
+ const Symbol *GetFirstSymbol() const { return complex_.GetFirstSymbol(); }
+ const Symbol *GetLastSymbol() const { return complex_.GetLastSymbol(); }
std::ostream &Dump(std::ostream &) const;
private:
Designator(DataRef &&that)
: u{common::MoveVariant<Variant>(std::move(that.u))} {}
- std::optional<DynamicType> GetType() const {
- if constexpr (std::is_same_v<Result, SomeDerived>) {
- if (const Symbol * sym{GetSymbol(false)}) {
- return GetSymbolType(*sym);
- } else {
- return std::nullopt;
- }
- } else {
- return Result::GetType();
- }
- }
-
- int Rank() const {
- return std::visit(
- common::visitors{[](const Symbol *sym) { return GetSymbolRank(*sym); },
- [](const auto &x) { return x.Rank(); }},
- u);
- }
-
- const Symbol *GetSymbol(bool first) const {
- return std::visit(common::visitors{[](const Symbol *sym) { return sym; },
- [=](const auto &x) { return x.GetSymbol(first); }},
- u);
- }
-
+ std::optional<DynamicType> GetType() const;
+ int Rank() const;
+ const Symbol *GetFirstSymbol() const;
+ const Symbol *GetLastSymbol() const;
Expr<SubscriptInteger> LEN() const;
-
- std::ostream &Dump(std::ostream &o) const {
- std::visit(common::visitors{[&](const Symbol *sym) {
- o << GetSymbolName(*sym).ToString();
- },
- [&](const auto &x) { x.Dump(o); }},
- u);
- return o;
- }
+ std::ostream &Dump(std::ostream &o) const;
Variant u;
};
// Wraps a data reference in a typed Designator<>.
static MaybeExpr Designate(DataRef &&dataRef) {
- const Symbol &symbol{*dataRef.GetSymbol(false)};
+ const Symbol &symbol{*dataRef.GetLastSymbol()};
if (std::optional<DynamicType> dyType{GetSymbolType(symbol)}) {
return TypedWrapper<Designator, DataRef>(
std::move(*dyType), std::move(dataRef));
GetSubstringBound(std::get<0>(range.t))};
std::optional<Expr<SubscriptInteger>> last{
GetSubstringBound(std::get<1>(range.t))};
- const Symbol &symbol{*checked->GetSymbol(false)};
+ const Symbol &symbol{*checked->GetLastSymbol()};
if (std::optional<DynamicType> dynamicType{GetSymbolType(symbol)}) {
if (dynamicType->category == TypeCategory::Character) {
return WrapperHelper<TypeCategory::Character, Designator,
}
MaybeExpr ExprAnalyzer::CompleteSubscripts(ArrayRef &&ref) {
- const Symbol &symbol{*ref.GetSymbol(false)};
+ const Symbol &symbol{*ref.GetLastSymbol()};
int symbolRank{symbol.Rank()};
if (ref.subscript.empty()) {
// A -> A(:,:)