// TODO: convenience wrappers for constructing conversions
#include "common.h"
+#include "expression-forward.h"
#include "type.h"
#include "variable.h"
#include "../lib/common/idioms.h"
void Fold(FoldingContext &);
+ // TODO: function reference
std::variant<Constant, common::Indirection<Designator>,
Convert<GenericIntegerExpr>, Convert<GenericRealExpr>, Parentheses,
Negate, Add, Subtract, Multiply, Divide, Power>
template<typename A>
Expr(std::enable_if_t<!std::is_reference_v<A>, A> &&x) : u{std::move(x)} {}
+ // TODO: designators, function references
std::variant<Constant, Convert<GenericIntegerExpr>, Convert<GenericRealExpr>,
Parentheses, Negate, Add, Subtract, Multiply, Divide, Power, IntPower,
RealPart, AIMAG>
template<typename A>
Expr(std::enable_if_t<!std::is_reference_v<A>, A> &&x) : u{std::move(x)} {}
+ // TODO: designators, function references
std::variant<Constant, Parentheses, Negate, Add, Subtract, Multiply, Divide,
Power, IntPower, CMPLX>
u;
LengthExpr LEN() const;
+ // TODO: designators, function references
std::variant<Constant, Binary<Expr>> u;
};
template<typename A>
Expr(std::enable_if_t<!std::is_reference_v<A>, A> &&x) : u{std::move(x)} {}
+ // TODO: designators, function references
std::variant<Constant, Not, And, Or, Eqv, Neqv,
CategoryComparison<Category::Integer>, CategoryComparison<Category::Real>,
CategoryComparison<Category::Complex>,
return Emit(o, u);
}
-std::ostream &ProcedureRef::Dump(std::ostream &o) const {
+template<typename ARG>
+std::ostream &ProcedureRef<ARG>::Dump(std::ostream &o) const {
Emit(o, proc);
char separator{'('};
for (const auto &arg : argument) {
std::ostream &Variable::Dump(std::ostream &o) const { return Emit(o, u); }
-std::ostream &ActualArg::Dump(std::ostream &o) const { return Emit(o, u); }
+std::ostream &ActualFunctionArg::Dump(std::ostream &o) const {
+ return Emit(o, u);
+}
+std::ostream &ActualSubroutineArg::Dump(std::ostream &o) const {
+ return Emit(o, u);
+}
std::ostream &Label::Dump(std::ostream &o) const {
return o << '*' << std::dec << label;
namespace Fortran::evaluate {
-struct DataRef;
-struct Variable;
-struct ActualArg;
-struct Label;
-
using semantics::Symbol;
+// TODO: Reference sections in the Standard
+
+struct DataRef;
struct Component {
CLASS_BOILERPLATE(Component)
Component(const DataRef &b, const Symbol &c) : base{b}, sym{&c} {}
std::vector<Subscript> subscript;
};
+struct Variable;
struct CoarrayRef {
CLASS_BOILERPLATE(CoarrayRef)
CoarrayRef(const Symbol &n, std::vector<SubscriptExpr> &&s)
std::variant<const Symbol *, Component> u;
};
-struct ProcedureRef { // TODO split off FunctionRef without alt returns
+template<typename ARG> struct ProcedureRef {
+ using ArgumentType = common::Indirection<ARG>;
CLASS_BOILERPLATE(ProcedureRef)
- ProcedureRef(
- ProcedureDesignator &&p, std::vector<common::Indirection<ActualArg>> &&a)
+ ProcedureRef(ProcedureDesignator &&p, std::vector<ArgumentType> &&a)
: proc{std::move(p)}, argument(std::move(a)) {}
ProcedureDesignator proc;
- std::vector<common::Indirection<ActualArg>> argument;
+ std::vector<ArgumentType> argument;
};
+struct ActualFunctionArg;
+using FunctionRef = ProcedureRef<ActualFunctionArg>;
+
struct Variable {
CLASS_BOILERPLATE(Variable)
explicit Variable(Designator &&d) : u{std::move(d)} {}
- explicit Variable(ProcedureRef &&p) : u{std::move(p)} {}
- std::variant<Designator, ProcedureRef> u;
+ explicit Variable(FunctionRef &&p) : u{std::move(p)} {}
+ std::variant<Designator, FunctionRef> u;
+};
+
+struct ActualFunctionArg {
+ CLASS_BOILERPLATE(ActualFunctionArg)
+ explicit ActualFunctionArg(GenericExpr &&x) : u{std::move(x)} {}
+ explicit ActualFunctionArg(Variable &&x) : u{std::move(x)} {}
+ std::variant<common::Indirection<GenericExpr>, Variable> u;
};
struct Label { // TODO: this is a placeholder
int label;
};
-struct ActualArg {
- CLASS_BOILERPLATE(ActualArg)
- explicit ActualArg(GenericExpr &&x) : u{std::move(x)} {}
- explicit ActualArg(Variable &&x) : u{std::move(x)} {}
- explicit ActualArg(const Label &l) : u{&l} {}
+struct ActualSubroutineArg {
+ CLASS_BOILERPLATE(ActualSubroutineArg)
+ explicit ActualSubroutineArg(GenericExpr &&x) : u{std::move(x)} {}
+ explicit ActualSubroutineArg(Variable &&x) : u{std::move(x)} {}
+ explicit ActualSubroutineArg(const Label &l) : u{&l} {}
std::variant<common::Indirection<GenericExpr>, Variable, const Label *> u;
};
+
+using SubroutineRef = ProcedureRef<ActualSubroutineArg>;
+
} // namespace Fortran::evaluate
// This inclusion must follow the definitions in this header due to