}
std::optional<GenericConstant> GenericExpr::ConstantValue() const {
- return std::visit([](const auto &x) -> std::optional<GenericConstant> {
- if (auto c{x.ConstantValue()}) {
- return {GenericConstant{std::move(*c)}};
- }
- return {};
- }, u);
+ return std::visit(
+ [](const auto &x) -> std::optional<GenericConstant> {
+ if (auto c{x.ConstantValue()}) {
+ return {GenericConstant{std::move(*c)}};
+ }
+ return {};
+ },
+ u);
}
-template<Category CAT> std::optional<CategoryConstant<CAT>> CategoryExpr<CAT>::ConstantValue() const {
- return std::visit([](const auto &x) -> std::optional<CategoryConstant<CAT>> {
- if (auto c{x.ConstantValue()}) {
- return {CategoryConstant<CAT>{std::move(*c)}};
- }
- return {};
- }, u);
+template<Category CAT>
+std::optional<CategoryConstant<CAT>> CategoryExpr<CAT>::ConstantValue() const {
+ return std::visit(
+ [](const auto &x) -> std::optional<CategoryConstant<CAT>> {
+ if (auto c{x.ConstantValue()}) {
+ return {CategoryConstant<CAT>{std::move(*c)}};
+ }
+ return {};
+ },
+ u);
}
template<Category CAT> void CategoryExpr<CAT>::Fold(FoldingContext &context) {
- std::visit([&](auto &x){ x.Fold(context); }, u);
+ std::visit([&](auto &x) { x.Fold(context); }, u);
}
void GenericExpr::Fold(FoldingContext &context) {
- std::visit([&](auto &x){ x.Fold(context); }, u);
+ std::visit([&](auto &x) { x.Fold(context); }, u);
}
template struct CategoryExpr<Category::Integer>;
template<Category CAT> struct CategoryComparison {
CLASS_BOILERPLATE(CategoryComparison)
template<int KIND> using KindComparison = Comparison<Expr<CAT, KIND>>;
- template<int KIND>
- CategoryComparison(const KindComparison<KIND> &x) : u{x} {}
+ template<int KIND> CategoryComparison(const KindComparison<KIND> &x) : u{x} {}
template<int KIND>
CategoryComparison(KindComparison<KIND> &&x) : u{std::move(x)} {}
std::optional<bool> Fold(FoldingContext &c);
CLASS_BOILERPLATE(CategoryConstant)
template<int KIND> using KindConstant = typename Expr<CAT, KIND>::Constant;
template<typename A> CategoryConstant(const A &x) : u{x} {}
- template<typename A> CategoryConstant(std::enable_if_t<!std::is_reference_v<A>, A> &&x) : u{std::move(x)} {}
+ template<typename A>
+ CategoryConstant(std::enable_if_t<!std::is_reference_v<A>, A> &&x)
+ : u{std::move(x)} {}
typename KindsVariant<CAT, KindConstant>::type u;
};
struct GenericConstant {
CLASS_BOILERPLATE(GenericConstant)
template<Category CAT, int KIND>
- GenericConstant(const typename Expr<CAT, KIND>::Constant &x) : u{CategoryConstant<CAT>{x}} {}
+ GenericConstant(const typename Expr<CAT, KIND>::Constant &x)
+ : u{CategoryConstant<CAT>{x}} {}
template<Category CAT, int KIND>
- GenericConstant(typename Expr<CAT, KIND>::Constant &&x) : u{CategoryConstant<CAT>{std::move(x)}} {}
+ GenericConstant(typename Expr<CAT, KIND>::Constant &&x)
+ : u{CategoryConstant<CAT>{std::move(x)}} {}
template<typename A> GenericConstant(const A &x) : u{x} {}
template<typename A>
GenericConstant(std::enable_if_t<!std::is_reference_v<A>, A> &&x)
: u{std::move(x)} {}
- std::variant<CategoryConstant<Category::Integer>, CategoryConstant<Category::Real>, CategoryConstant<Category::Complex>, CategoryConstant<Category::Character>, bool> u;
+ std::variant<CategoryConstant<Category::Integer>,
+ CategoryConstant<Category::Real>, CategoryConstant<Category::Complex>,
+ CategoryConstant<Category::Character>, bool>
+ u;
};
// Dynamically polymorphic expressions that can hold any supported kind
// These macros invoke other macros on each of the supported kinds of
// a given category.
#define COMMA ,
-#define FOR_EACH_INTEGER_KIND(M,SEP) M(1) SEP M(2) SEP M(4) SEP M(8) SEP M(16)
-#define FOR_EACH_REAL_KIND(M,SEP) M(2) SEP M(4) SEP M(8) SEP M(10) SEP M(16)
-#define FOR_EACH_COMPLEX_KIND(M,SEP) FOR_EACH_REAL_KIND(M,SEP)
-#define FOR_EACH_CHARACTER_KIND(M,SEP) M(1)
-#define FOR_EACH_LOGICAL_KIND(M,SEP) M(1) SEP M(2) SEP M(4) SEP M(8)
+#define FOR_EACH_INTEGER_KIND(M, SEP) M(1) SEP M(2) SEP M(4) SEP M(8) SEP M(16)
+#define FOR_EACH_REAL_KIND(M, SEP) M(2) SEP M(4) SEP M(8) SEP M(10) SEP M(16)
+#define FOR_EACH_COMPLEX_KIND(M, SEP) FOR_EACH_REAL_KIND(M, SEP)
+#define FOR_EACH_CHARACTER_KIND(M, SEP) M(1)
+#define FOR_EACH_LOGICAL_KIND(M, SEP) M(1) SEP M(2) SEP M(4) SEP M(8)
// These templates create instances of std::variant<> that can contain
// applications of some class template to all of the supported kinds of
#define TKIND(K) T<K>
template<Category CAT, template<int> class T> struct KindsVariant;
template<template<int> class T> struct KindsVariant<Category::Integer, T> {
- using type = std::variant<FOR_EACH_INTEGER_KIND(TKIND,COMMA)>;
+ using type = std::variant<FOR_EACH_INTEGER_KIND(TKIND, COMMA)>;
};
// TODO use FOR_EACH...
template<template<int> class T> struct KindsVariant<Category::Real, T> {
namespace Fortran::semantics {
template<typename A>
-std::optional<evaluate::GenericExpr> AnalyzeHelper(ExpressionAnalyzer &ea, const A &tree) {
+std::optional<evaluate::GenericExpr> AnalyzeHelper(
+ ExpressionAnalyzer &ea, const A &tree) {
return ea.Analyze(tree);
}
template<typename A>
-std::optional<evaluate::GenericExpr> AnalyzeHelper(ExpressionAnalyzer &ea,
- const parser::Scalar<A> &tree) {
+std::optional<evaluate::GenericExpr> AnalyzeHelper(
+ ExpressionAnalyzer &ea, const parser::Scalar<A> &tree) {
std::optional<evaluate::GenericExpr> result{AnalyzeHelper(ea, tree.thing)};
if (result.has_value()) {
if (result->Rank() > 1) {
}
template<typename A>
-std::optional<evaluate::GenericExpr> AnalyzeHelper(ExpressionAnalyzer &ea,
- const parser::Constant<A> &tree) {
+std::optional<evaluate::GenericExpr> AnalyzeHelper(
+ ExpressionAnalyzer &ea, const parser::Constant<A> &tree) {
std::optional<evaluate::GenericExpr> result{AnalyzeHelper(ea, tree.thing)};
if (result.has_value()) {
result->Fold(ea.context());
}
template<typename A>
-std::optional<evaluate::GenericExpr> AnalyzeHelper(ExpressionAnalyzer &ea,
- const parser::Integer<A> &tree) {
+std::optional<evaluate::GenericExpr> AnalyzeHelper(
+ ExpressionAnalyzer &ea, const parser::Integer<A> &tree) {
std::optional<evaluate::GenericExpr> result{AnalyzeHelper(ea, tree.thing)};
- if (result.has_value() && !std::holds_alternative<evaluate::GenericIntegerExpr>(result->u)) {
+ if (result.has_value() &&
+ !std::holds_alternative<evaluate::GenericIntegerExpr>(result->u)) {
ea.Say("must be integer"_err_en_US);
return {};
}
return result;
}
-template<> std::optional<evaluate::GenericExpr> AnalyzeHelper(ExpressionAnalyzer &ea,
- const parser::Name &n) {
+template<>
+std::optional<evaluate::GenericExpr> AnalyzeHelper(
+ ExpressionAnalyzer &ea, const parser::Name &n) {
// TODO
return {};
}
-ExpressionAnalyzer::KindParam
-ExpressionAnalyzer::Analyze(const std::optional<parser::KindParam> &kindParam,
- KindParam defaultKind, KindParam kanjiKind) {
+ExpressionAnalyzer::KindParam ExpressionAnalyzer::Analyze(
+ const std::optional<parser::KindParam> &kindParam, KindParam defaultKind,
+ KindParam kanjiKind) {
if (!kindParam.has_value()) {
return defaultKind;
}
- return std::visit(common::visitors{[](std::uint64_t k) { return static_cast<KindParam>(k); },
- [&](const parser::Scalar<parser::Integer<parser::Constant<parser::Name>>> &n) {
- if (std::optional<evaluate::GenericExpr> oge{AnalyzeHelper(*this, n)}) {
- if (std::optional<evaluate::GenericConstant> ogc{oge->ConstantValue()}) {
- // TODO pmk more here next
- }
- }
- return defaultKind;
- },
- [&](parser::KindParam::Kanji) {
- if (kanjiKind >= 0) {
- return kanjiKind;
- }
- Say("Kanji not allowed here"_err_en_US);
- return defaultKind; }}, kindParam->u);
+ return std::visit(
+ common::visitors{
+ [](std::uint64_t k) { return static_cast<KindParam>(k); },
+ [&](const parser::Scalar<
+ parser::Integer<parser::Constant<parser::Name>>> &n) {
+ if (std::optional<evaluate::GenericExpr> oge{
+ AnalyzeHelper(*this, n)}) {
+ if (std::optional<evaluate::GenericConstant> ogc{
+ oge->ConstantValue()}) {
+ // TODO pmk more here next
+ }
+ }
+ return defaultKind;
+ },
+ [&](parser::KindParam::Kanji) {
+ if (kanjiKind >= 0) {
+ return kanjiKind;
+ }
+ Say("Kanji not allowed here"_err_en_US);
+ return defaultKind;
+ }},
+ kindParam->u);
}
-template<> std::optional<evaluate::GenericExpr> AnalyzeHelper(ExpressionAnalyzer &ea,
- const parser::IntLiteralConstant &x) {
+template<>
+std::optional<evaluate::GenericExpr> AnalyzeHelper(
+ ExpressionAnalyzer &ea, const parser::IntLiteralConstant &x) {
auto kind{ea.Analyze(std::get<std::optional<parser::KindParam>>(x.t),
- ea.defaultIntegerKind())};
+ ea.defaultIntegerKind())};
std::uint64_t value{std::get<std::uint64_t>(x.t)};
switch (kind) {
-#define CASE(k) case k: return {evaluate::GenericExpr{evaluate::GenericIntegerExpr{evaluate::IntegerExpr<k>{value}}}};
- FOR_EACH_INTEGER_KIND(CASE,)
+#define CASE(k) \
+ case k: \
+ return {evaluate::GenericExpr{ \
+ evaluate::GenericIntegerExpr{evaluate::IntegerExpr<k>{value}}}};
+ FOR_EACH_INTEGER_KIND(CASE, )
#undef CASE
default:
ea.Say(parser::MessageFormattedText{
- "unimplemented INTEGER kind (%ju)"_err_en_US,
- static_cast<std::uintmax_t>(kind)});
+ "unimplemented INTEGER kind (%ju)"_err_en_US,
+ static_cast<std::uintmax_t>(kind)});
return {};
}
}
-template<> std::optional<evaluate::GenericExpr> AnalyzeHelper(ExpressionAnalyzer &ea,
- const parser::LiteralConstant &x) {
+template<>
+std::optional<evaluate::GenericExpr> AnalyzeHelper(
+ ExpressionAnalyzer &ea, const parser::LiteralConstant &x) {
return std::visit(
- common::visitors{
- [&](const parser::IntLiteralConstant &c) { return AnalyzeHelper(ea, c); },
- // TODO next [&](const parser::RealLiteralConstant &c) { return AnalyzeHelper(ea, c); },
+ common::visitors{[&](const parser::IntLiteralConstant &c) {
+ return AnalyzeHelper(ea, c);
+ },
+ // TODO next [&](const parser::RealLiteralConstant &c) { return
+ // AnalyzeHelper(ea, c); },
// TODO: remaining cases
[&](const auto &) { return std::optional<evaluate::GenericExpr>{}; }},
x.u);
std::optional<evaluate::GenericExpr> ExpressionAnalyzer::Analyze(
const parser::Expr &x) {
return std::visit(
- common::visitors{
- [&](const parser::LiteralConstant &c) { return AnalyzeHelper(*this, c); },
+ common::visitors{[&](const parser::LiteralConstant &c) {
+ return AnalyzeHelper(*this, c);
+ },
// TODO: remaining cases
[&](const auto &) { return std::optional<evaluate::GenericExpr>{}; }},
x.u);