blob: 76425e1cd4d0704c345429cd28689e5be408aa16 [file] [log] [blame]
peter klausler79d044e2018-03-01 00:56:101// Generates Fortran from the content of a parse tree, using the
2// traversal templates in parse-tree-visitor.h.
3
Tim Keith2af29bc2018-02-26 22:28:324#include "unparse.h"
peter klausler79d044e2018-03-01 00:56:105#include "characters.h"
Tim Keith2af29bc2018-02-26 22:28:326#include "idioms.h"
7#include "indirection.h"
8#include "parse-tree-visitor.h"
9#include "parse-tree.h"
peter klausler79d044e2018-03-01 00:56:1010#include <algorithm>
peter klausler424ec7b2018-03-20 17:59:0711#include <cinttypes>
12#include <cstddef>
peter klausler4e354d82018-03-30 22:23:3713#include <set>
Tim Keith2af29bc2018-02-26 22:28:3214
15namespace Fortran {
16namespace parser {
17
18class UnparseVisitor {
19public:
peter klauslerb7cf5122018-03-14 22:31:1620 UnparseVisitor(std::ostream &out, int indentationAmount, Encoding encoding,
21 bool capitalize)
22 : out_{out}, indentationAmount_{indentationAmount}, encoding_{encoding},
23 capitalizeKeywords_{capitalize} {}
Tim Keith2af29bc2018-02-26 22:28:3224
peter klausler8ea4a0a2018-04-06 20:13:2025 // In nearly all cases, this code avoids defining Boolean-valued Pre()
26 // callbacks for the parse tree walking framework in favor of two void
27 // functions, Before() and Unparse(), which imply true and false return
28 // values for Pre() respectively.
29 template<typename T> void Before(const T &) {}
30 template<typename T> double Unparse(const T &); // not void, never used
31
peter klausler022a91b2018-04-26 22:44:2932 template<typename T> bool Pre(const T &x) {
33 if constexpr (std::is_void_v<decltype(Unparse(x))>) {
34 // There is a local definition of Unparse() for this type. It
35 // overrides the parse tree walker's default Walk() over the descendents.
36 Before(x);
37 Unparse(x);
38 Post(x);
39 return false; // Walk() does not visit descendents
40 } else {
41 Before(x);
42 return true; // there's no Unparse() defined here, Walk() the descendents
43 }
peter klausler8ea4a0a2018-04-06 20:13:2044 }
Tim Keith2af29bc2018-02-26 22:28:3245 template<typename T> void Post(const T &) {}
46
Tim Keith2af29bc2018-02-26 22:28:3247 // Emit simple types as-is.
peter klausler8ea4a0a2018-04-06 20:13:2048 void Unparse(const std::string &x) { Put(x); }
49 void Unparse(int x) { Put(std::to_string(x)); }
50 void Unparse(std::uint64_t x) { Put(std::to_string(x)); }
51 void Unparse(std::int64_t x) { Put(std::to_string(x)); }
52 void Unparse(char x) { Put(x); }
Tim Keith2af29bc2018-02-26 22:28:3253
peter klausler79d044e2018-03-01 00:56:1054 // Statement labels and ends of lines
peter klausler8ea4a0a2018-04-06 20:13:2055 template<typename T> void Before(const Statement<T> &x) {
peter klausler79d044e2018-03-01 00:56:1056 Walk(x.label, " ");
Tim Keith2af29bc2018-02-26 22:28:3257 }
peter klausler79d044e2018-03-01 00:56:1058 template<typename T> void Post(const Statement<T> &) { Put('\n'); }
59
60 // The special-case formatting functions for these productions are
61 // ordered to correspond roughly to their order of appearance in
62 // the Fortran 2018 standard (and parse-tree.h).
63
peter klausler8ea4a0a2018-04-06 20:13:2064 void Unparse(const Program &x) { // R501
65 Walk("", x.v, "\n"); // put blank lines between ProgramUnits
Tim Keith2af29bc2018-02-26 22:28:3266 }
peter klausler424ec7b2018-03-20 17:59:0767
peter klausler8ea4a0a2018-04-06 20:13:2068 void Unparse(const Name &x) { // R603
peter klausler938d1eb2018-03-23 21:18:5969 Put(x.ToString());
peter klausler424ec7b2018-03-20 17:59:0770 }
peter klausler8ea4a0a2018-04-06 20:13:2071 void Unparse(const DefinedOperator::IntrinsicOperator &x) { // R608
peter klausler79d044e2018-03-01 00:56:1072 switch (x) {
73 case DefinedOperator::IntrinsicOperator::Power: Put("**"); break;
74 case DefinedOperator::IntrinsicOperator::Multiply: Put('*'); break;
75 case DefinedOperator::IntrinsicOperator::Divide: Put('/'); break;
76 case DefinedOperator::IntrinsicOperator::Add: Put('+'); break;
77 case DefinedOperator::IntrinsicOperator::Subtract: Put('-'); break;
78 case DefinedOperator::IntrinsicOperator::Concat: Put("//"); break;
79 case DefinedOperator::IntrinsicOperator::LT: Put('<'); break;
80 case DefinedOperator::IntrinsicOperator::LE: Put("<="); break;
81 case DefinedOperator::IntrinsicOperator::EQ: Put("=="); break;
82 case DefinedOperator::IntrinsicOperator::NE: Put("/="); break;
83 case DefinedOperator::IntrinsicOperator::GE: Put(">="); break;
84 case DefinedOperator::IntrinsicOperator::GT: Put('>'); break;
peter klausler8ea4a0a2018-04-06 20:13:2085 default: Put('.'), Word(DefinedOperator::EnumToString(x)), Put('.');
Tim Keith2af29bc2018-02-26 22:28:3286 }
Tim Keith2af29bc2018-02-26 22:28:3287 }
peter klausler79d044e2018-03-01 00:56:1088 void Post(const Star &) { Put('*'); } // R701 &c.
89 void Post(const TypeParamValue::Deferred &) { Put(':'); } // R701
peter klausler8ea4a0a2018-04-06 20:13:2090 void Unparse(const DeclarationTypeSpec::Type &x) { // R703
peter klauslerb7cf5122018-03-14 22:31:1691 Word("TYPE("), Walk(x.derived), Put(')');
Tim Keith2af29bc2018-02-26 22:28:3292 }
peter klausler8ea4a0a2018-04-06 20:13:2093 void Unparse(const DeclarationTypeSpec::Class &x) {
peter klauslerb7cf5122018-03-14 22:31:1694 Word("CLASS("), Walk(x.derived), Put(')');
Tim Keith2af29bc2018-02-26 22:28:3295 }
peter klauslerb7cf5122018-03-14 22:31:1696 void Post(const DeclarationTypeSpec::ClassStar &) { Word("CLASS(*)"); }
97 void Post(const DeclarationTypeSpec::TypeStar &) { Word("TYPE(*)"); }
peter klausler8ea4a0a2018-04-06 20:13:2098 void Unparse(const DeclarationTypeSpec::Record &x) {
peter klauslerb7cf5122018-03-14 22:31:1699 Word("RECORD/"), Walk(x.v), Put('/');
Tim Keith2af29bc2018-02-26 22:28:32100 }
peter klausler8ea4a0a2018-04-06 20:13:20101 void Before(const IntrinsicTypeSpec::Real &x) { // R704
peter klauslerb7cf5122018-03-14 22:31:16102 Word("REAL");
Tim Keith2af29bc2018-02-26 22:28:32103 }
peter klausler8ea4a0a2018-04-06 20:13:20104 void Before(const IntrinsicTypeSpec::Complex &x) { Word("COMPLEX"); }
peter klausler79d044e2018-03-01 00:56:10105 void Post(const IntrinsicTypeSpec::DoublePrecision &) {
peter klauslerb7cf5122018-03-14 22:31:16106 Word("DOUBLE PRECISION");
peter klausler79d044e2018-03-01 00:56:10107 }
peter klausler8ea4a0a2018-04-06 20:13:20108 void Before(const IntrinsicTypeSpec::Character &x) { Word("CHARACTER"); }
109 void Before(const IntrinsicTypeSpec::Logical &x) { Word("LOGICAL"); }
peter klauslerb7cf5122018-03-14 22:31:16110 void Post(const IntrinsicTypeSpec::DoubleComplex &) {
111 Word("DOUBLE COMPLEX");
112 }
peter klausler8ea4a0a2018-04-06 20:13:20113 void Before(const IntrinsicTypeSpec::NCharacter &x) { Word("NCHARACTER"); }
114 void Before(const IntegerTypeSpec &x) { // R705
peter klauslerb7cf5122018-03-14 22:31:16115 Word("INTEGER");
Tim Keith2af29bc2018-02-26 22:28:32116 }
peter klausler8ea4a0a2018-04-06 20:13:20117 void Unparse(const KindSelector &x) { // R706
peter klausler79d044e2018-03-01 00:56:10118 std::visit(
119 visitors{[&](const ScalarIntConstantExpr &y) {
peter klauslerb7cf5122018-03-14 22:31:16120 Put('('), Word("KIND="), Walk(y), Put(')');
peter klausler79d044e2018-03-01 00:56:10121 },
122 [&](const KindSelector::StarSize &y) { Put('*'), Walk(y.v); }},
123 x.u);
peter klausler79d044e2018-03-01 00:56:10124 }
peter klausler8ea4a0a2018-04-06 20:13:20125 void Unparse(const SignedIntLiteralConstant &x) { // R707
peter klausler79d044e2018-03-01 00:56:10126 Walk(std::get<std::int64_t>(x.t));
127 Walk("_", std::get<std::optional<KindParam>>(x.t));
peter klausler79d044e2018-03-01 00:56:10128 }
peter klausler8ea4a0a2018-04-06 20:13:20129 void Unparse(const IntLiteralConstant &x) { // R708
peter klausler79d044e2018-03-01 00:56:10130 Walk(std::get<std::uint64_t>(x.t));
131 Walk("_", std::get<std::optional<KindParam>>(x.t));
peter klausler79d044e2018-03-01 00:56:10132 }
peter klausler8ea4a0a2018-04-06 20:13:20133 void Unparse(const Sign &x) { // R712
peter klausler79d044e2018-03-01 00:56:10134 Put(x == Sign::Negative ? '-' : '+');
peter klausler79d044e2018-03-01 00:56:10135 }
peter klausler8ea4a0a2018-04-06 20:13:20136 void Unparse(const RealLiteralConstant &x) { // R714, R715
peter klausler424ec7b2018-03-20 17:59:07137 Put(x.real.source.ToString()), Walk("_", x.kind);
peter klausler79d044e2018-03-01 00:56:10138 }
peter klausler8ea4a0a2018-04-06 20:13:20139 void Unparse(const ComplexLiteralConstant &x) { // R718 - R720
peter klausler79d044e2018-03-01 00:56:10140 Put('('), Walk(x.t, ","), Put(')');
peter klausler79d044e2018-03-01 00:56:10141 }
peter klausler8ea4a0a2018-04-06 20:13:20142 void Unparse(const CharSelector::LengthAndKind &x) { // R721
peter klauslerb7cf5122018-03-14 22:31:16143 Put('('), Word("KIND="), Walk(x.kind);
144 Walk(", LEN=", x.length), Put(')');
peter klausler79d044e2018-03-01 00:56:10145 }
peter klausler8ea4a0a2018-04-06 20:13:20146 void Unparse(const LengthSelector &x) { // R722
peter klausler79d044e2018-03-01 00:56:10147 std::visit(visitors{[&](const TypeParamValue &y) {
peter klauslerb7cf5122018-03-14 22:31:16148 Put('('), Word("LEN="), Walk(y), Put(')');
peter klausler79d044e2018-03-01 00:56:10149 },
150 [&](const CharLength &y) { Put('*'), Walk(y); }},
151 x.u);
peter klausler79d044e2018-03-01 00:56:10152 }
peter klausler8ea4a0a2018-04-06 20:13:20153 void Unparse(const CharLength &x) { // R723
peter klausler79d044e2018-03-01 00:56:10154 std::visit(
155 visitors{[&](const TypeParamValue &y) { Put('('), Walk(y), Put(')'); },
156 [&](const std::int64_t &y) { Walk(y); }},
157 x.u);
peter klausler79d044e2018-03-01 00:56:10158 }
peter klausler8ea4a0a2018-04-06 20:13:20159 void Unparse(const CharLiteralConstant &x) { // R724
peter klausler79d044e2018-03-01 00:56:10160 if (const auto &k = std::get<std::optional<KindParam>>(x.t)) {
161 if (std::holds_alternative<KindParam::Kanji>(k->u)) {
peter klauslerb7cf5122018-03-14 22:31:16162 Word("NC");
peter klausler79d044e2018-03-01 00:56:10163 } else {
164 Walk(*k), Put('_');
165 }
166 }
167 PutQuoted(std::get<std::string>(x.t));
peter klausler79d044e2018-03-01 00:56:10168 }
peter klausler8ea4a0a2018-04-06 20:13:20169 void Before(const HollerithLiteralConstant &x) {
peter klausler424ec7b2018-03-20 17:59:07170 std::optional<std::size_t> chars{CountCharacters(x.v.data(), x.v.size(),
peter klausler79d044e2018-03-01 00:56:10171 encoding_ == Encoding::EUC_JP ? EUC_JPCharacterBytes
172 : UTF8CharacterBytes)};
173 if (chars.has_value()) {
174 Pre(*chars);
175 } else {
176 Pre(x.v.size());
177 }
178 Put('H');
Tim Keith2af29bc2018-02-26 22:28:32179 }
peter klausler8ea4a0a2018-04-06 20:13:20180 void Unparse(const LogicalLiteralConstant &x) { // R725
peter klausler42b72c42018-03-15 17:59:46181 Put(std::get<bool>(x.t) ? ".TRUE." : ".FALSE.");
182 Walk("_", std::get<std::optional<KindParam>>(x.t));
Tim Keith2af29bc2018-02-26 22:28:32183 }
peter klausler8ea4a0a2018-04-06 20:13:20184 void Unparse(const DerivedTypeStmt &x) { // R727
peter klauslerb7cf5122018-03-14 22:31:16185 Word("TYPE"), Walk(", ", std::get<std::list<TypeAttrSpec>>(x.t), ", ");
peter klausler424ec7b2018-03-20 17:59:07186 Put(" :: "), Walk(std::get<Name>(x.t));
peter klausler79d044e2018-03-01 00:56:10187 Walk("(", std::get<std::list<Name>>(x.t), ", ", ")");
Tim Keith2af29bc2018-02-26 22:28:32188 Indent();
Tim Keith2af29bc2018-02-26 22:28:32189 }
peter klausler8ea4a0a2018-04-06 20:13:20190 void Unparse(const Abstract &x) { // R728, &c.
peter klauslerb7cf5122018-03-14 22:31:16191 Word("ABSTRACT");
Tim Keith2af29bc2018-02-26 22:28:32192 }
peter klauslerd71f3cf2018-03-14 23:31:41193 void Post(const TypeAttrSpec::BindC &) { Word("BIND(C)"); }
peter klausler8ea4a0a2018-04-06 20:13:20194 void Unparse(const TypeAttrSpec::Extends &x) {
peter klauslerb7cf5122018-03-14 22:31:16195 Word("EXTENDS("), Walk(x.v), Put(')');
Tim Keith2af29bc2018-02-26 22:28:32196 }
peter klausler8ea4a0a2018-04-06 20:13:20197 void Unparse(const EndTypeStmt &x) { // R730
peter klauslerb7cf5122018-03-14 22:31:16198 Outdent(), Word("END TYPE"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10199 }
peter klausler8ea4a0a2018-04-06 20:13:20200 void Unparse(const SequenceStmt &x) { // R731
peter klauslerb7cf5122018-03-14 22:31:16201 Word("SEQUENCE");
Tim Keith2af29bc2018-02-26 22:28:32202 }
peter klausler8ea4a0a2018-04-06 20:13:20203 void Unparse(const TypeParamDefStmt &x) { // R732
peter klausler79d044e2018-03-01 00:56:10204 Walk(std::get<IntegerTypeSpec>(x.t));
205 Put(", "), Walk(std::get<TypeParamDefStmt::KindOrLen>(x.t));
206 Put(" :: "), Walk(std::get<std::list<TypeParamDecl>>(x.t), ", ");
Tim Keith2af29bc2018-02-26 22:28:32207 }
peter klausler8ea4a0a2018-04-06 20:13:20208 void Unparse(const TypeParamDecl &x) { // R733
peter klausler424ec7b2018-03-20 17:59:07209 Walk(std::get<Name>(x.t));
peter klausler79d044e2018-03-01 00:56:10210 Walk("=", std::get<std::optional<ScalarIntConstantExpr>>(x.t));
Tim Keith2af29bc2018-02-26 22:28:32211 }
peter klausler8ea4a0a2018-04-06 20:13:20212 void Unparse(const DataComponentDefStmt &x) { // R737
peter klausler79d044e2018-03-01 00:56:10213 const auto &dts = std::get<DeclarationTypeSpec>(x.t);
214 const auto &attrs = std::get<std::list<ComponentAttrSpec>>(x.t);
215 const auto &decls = std::get<std::list<ComponentDecl>>(x.t);
216 Walk(dts), Walk(", ", attrs, ", ");
217 if (!attrs.empty() ||
218 (!std::holds_alternative<DeclarationTypeSpec::Record>(dts.u) &&
219 std::none_of(
220 decls.begin(), decls.end(), [](const ComponentDecl &d) {
221 const auto &init =
222 std::get<std::optional<Initialization>>(d.t);
223 return init.has_value() &&
224 std::holds_alternative<
225 std::list<Indirection<DataStmtValue>>>(init->u);
226 }))) {
227 Put(" ::");
228 }
229 Put(' '), Walk(decls, ", ");
Tim Keith2af29bc2018-02-26 22:28:32230 }
peter klausler8ea4a0a2018-04-06 20:13:20231 void Unparse(const Allocatable &x) { // R738
peter klauslerb7cf5122018-03-14 22:31:16232 Word("ALLOCATABLE");
Tim Keith2af29bc2018-02-26 22:28:32233 }
peter klausler8ea4a0a2018-04-06 20:13:20234 void Unparse(const Pointer &x) { Word("POINTER"); }
235 void Unparse(const Contiguous &x) { Word("CONTIGUOUS"); }
236 void Before(const ComponentAttrSpec &x) {
peter klauslerb7cf5122018-03-14 22:31:16237 std::visit(visitors{[&](const CoarraySpec &) { Word("CODIMENSION["); },
238 [&](const ComponentArraySpec &) { Word("DIMENSION("); },
peter klauslerd71f3cf2018-03-14 23:31:41239 [](const auto &) {}},
peter klausler79d044e2018-03-01 00:56:10240 x.u);
Tim Keith2af29bc2018-02-26 22:28:32241 }
peter klausler79d044e2018-03-01 00:56:10242 void Post(const ComponentAttrSpec &x) {
peter klauslerd71f3cf2018-03-14 23:31:41243 std::visit(
244 visitors{[&](const CoarraySpec &) { Put(']'); },
245 [&](const ComponentArraySpec &) { Put(')'); }, [](const auto &) {}},
peter klausler79d044e2018-03-01 00:56:10246 x.u);
247 }
peter klausler8ea4a0a2018-04-06 20:13:20248 void Unparse(const ComponentDecl &x) { // R739
peter klausler79d044e2018-03-01 00:56:10249 Walk(std::get<ObjectName>(x.t));
250 Walk("(", std::get<std::optional<ComponentArraySpec>>(x.t), ")");
251 Walk("[", std::get<std::optional<CoarraySpec>>(x.t), "]");
252 Walk("*", std::get<std::optional<CharLength>>(x.t));
253 Walk(std::get<std::optional<Initialization>>(x.t));
peter klausler79d044e2018-03-01 00:56:10254 }
peter klausler8ea4a0a2018-04-06 20:13:20255 void Unparse(const ComponentArraySpec &x) { // R740
peter klausler79d044e2018-03-01 00:56:10256 std::visit(
257 visitors{[&](const std::list<ExplicitShapeSpec> &y) { Walk(y, ","); },
258 [&](const DeferredShapeSpecList &y) { Walk(y); }},
259 x.u);
peter klausler79d044e2018-03-01 00:56:10260 }
peter klausler8ea4a0a2018-04-06 20:13:20261 void Unparse(const ProcComponentDefStmt &x) { // R741
peter klauslerb7cf5122018-03-14 22:31:16262 Word("PROCEDURE(");
peter klausler79d044e2018-03-01 00:56:10263 Walk(std::get<std::optional<ProcInterface>>(x.t)), Put(')');
264 Walk(", ", std::get<std::list<ProcComponentAttrSpec>>(x.t), ", ");
265 Put(" :: "), Walk(std::get<std::list<ProcDecl>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:10266 }
peter klausler8ea4a0a2018-04-06 20:13:20267 void Unparse(const NoPass &x) { // R742
peter klauslerb7cf5122018-03-14 22:31:16268 Word("NOPASS");
peter klausler79d044e2018-03-01 00:56:10269 }
peter klausler8ea4a0a2018-04-06 20:13:20270 void Unparse(const Pass &x) { Word("PASS"), Walk("(", x.v, ")"); }
271 void Unparse(const Initialization &x) { // R743 & R805
peter klausler79d044e2018-03-01 00:56:10272 std::visit(visitors{[&](const ConstantExpr &y) { Put(" = "), Walk(y); },
273 [&](const NullInit &y) { Put(" => "), Walk(y); },
274 [&](const InitialDataTarget &y) { Put(" => "), Walk(y); },
275 [&](const std::list<Indirection<DataStmtValue>> &y) {
276 Walk("/", y, ", ", "/");
277 }},
278 x.u);
peter klausler79d044e2018-03-01 00:56:10279 }
peter klausler8ea4a0a2018-04-06 20:13:20280 void Unparse(const PrivateStmt &x) { // R745
peter klauslerb7cf5122018-03-14 22:31:16281 Word("PRIVATE");
peter klausler79d044e2018-03-01 00:56:10282 }
peter klausler8ea4a0a2018-04-06 20:13:20283 void Unparse(const TypeBoundProcedureStmt::WithoutInterface &x) { // R749
peter klauslerb7cf5122018-03-14 22:31:16284 Word("PROCEDURE"), Walk(", ", x.attributes, ", ");
peter klauslerdcd09422018-03-15 23:03:28285 Put(" :: "), Walk(x.declarations, ", ");
peter klausler79d044e2018-03-01 00:56:10286 }
peter klausler8ea4a0a2018-04-06 20:13:20287 void Unparse(const TypeBoundProcedureStmt::WithInterface &x) {
peter klauslerb7cf5122018-03-14 22:31:16288 Word("PROCEDURE("), Walk(x.interfaceName), Put("), ");
peter klausler79d044e2018-03-01 00:56:10289 Walk(x.attributes);
peter klauslerdcd09422018-03-15 23:03:28290 Put(" :: "), Walk(x.bindingNames, ", ");
peter klausler79d044e2018-03-01 00:56:10291 }
peter klausler8ea4a0a2018-04-06 20:13:20292 void Unparse(const TypeBoundProcDecl &x) { // R750
peter klausler79d044e2018-03-01 00:56:10293 Walk(std::get<Name>(x.t));
294 Walk(" => ", std::get<std::optional<Name>>(x.t));
peter klausler79d044e2018-03-01 00:56:10295 }
peter klausler8ea4a0a2018-04-06 20:13:20296 void Unparse(const TypeBoundGenericStmt &x) { // R751
peter klauslerb7cf5122018-03-14 22:31:16297 Word("GENERIC"), Walk(", ", std::get<std::optional<AccessSpec>>(x.t));
peter klausler79d044e2018-03-01 00:56:10298 Put(" :: "), Walk(std::get<Indirection<GenericSpec>>(x.t));
299 Put(" => "), Walk(std::get<std::list<Name>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:10300 }
peter klauslerb7cf5122018-03-14 22:31:16301 void Post(const BindAttr::Deferred &) { Word("DEFERRED"); } // R752
302 void Post(const BindAttr::Non_Overridable &) { Word("NON_OVERRIDABLE"); }
peter klausler8ea4a0a2018-04-06 20:13:20303 void Unparse(const FinalProcedureStmt &x) { // R753
peter klausler62d9cdd2018-03-15 00:02:21304 Word("FINAL :: "), Walk(x.v, ", ");
peter klauslerb7cf5122018-03-14 22:31:16305 }
peter klausler8ea4a0a2018-04-06 20:13:20306 void Unparse(const DerivedTypeSpec &x) { // R754
peter klausler79d044e2018-03-01 00:56:10307 Walk(std::get<Name>(x.t));
308 Walk("(", std::get<std::list<TypeParamSpec>>(x.t), ",", ")");
peter klausler79d044e2018-03-01 00:56:10309 }
peter klausler8ea4a0a2018-04-06 20:13:20310 void Unparse(const TypeParamSpec &x) { // R755
peter klausler79d044e2018-03-01 00:56:10311 Walk(std::get<std::optional<Keyword>>(x.t), "=");
312 Walk(std::get<TypeParamValue>(x.t));
peter klausler79d044e2018-03-01 00:56:10313 }
peter klausler8ea4a0a2018-04-06 20:13:20314 void Unparse(const StructureConstructor &x) { // R756
peter klausler79d044e2018-03-01 00:56:10315 Walk(std::get<DerivedTypeSpec>(x.t));
316 Put('('), Walk(std::get<std::list<ComponentSpec>>(x.t), ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10317 }
peter klausler8ea4a0a2018-04-06 20:13:20318 void Unparse(const ComponentSpec &x) { // R757
peter klausler79d044e2018-03-01 00:56:10319 Walk(std::get<std::optional<Keyword>>(x.t), "=");
320 Walk(std::get<ComponentDataSource>(x.t));
peter klausler79d044e2018-03-01 00:56:10321 }
peter klausler8ea4a0a2018-04-06 20:13:20322 void Unparse(const EnumDefStmt &) { // R760
peter klausler62d9cdd2018-03-15 00:02:21323 Word("ENUM, BIND(C)"), Indent();
peter klausler79d044e2018-03-01 00:56:10324 }
peter klausler8ea4a0a2018-04-06 20:13:20325 void Unparse(const EnumeratorDefStmt &x) { // R761
peter klausler62d9cdd2018-03-15 00:02:21326 Word("ENUMERATOR :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10327 }
peter klausler8ea4a0a2018-04-06 20:13:20328 void Unparse(const Enumerator &x) { // R762
peter klausler79d044e2018-03-01 00:56:10329 Walk(std::get<NamedConstant>(x.t));
330 Walk(" = ", std::get<std::optional<ScalarIntConstantExpr>>(x.t));
peter klausler79d044e2018-03-01 00:56:10331 }
332 void Post(const EndEnumStmt &) { // R763
peter klausler62d9cdd2018-03-15 00:02:21333 Outdent(), Word("END ENUM");
peter klausler79d044e2018-03-01 00:56:10334 }
peter klausler8ea4a0a2018-04-06 20:13:20335 void Unparse(const BOZLiteralConstant &x) { // R764 - R767
peter klausler79d044e2018-03-01 00:56:10336 Put("Z'");
337 out_ << std::hex << x.v << std::dec << '\'';
peter klausler79d044e2018-03-01 00:56:10338 }
peter klausler8ea4a0a2018-04-06 20:13:20339 void Unparse(const AcValue::Triplet &x) { // R773
peter klausler79d044e2018-03-01 00:56:10340 Walk(std::get<0>(x.t)), Put(':'), Walk(std::get<1>(x.t));
341 Walk(":", std::get<std::optional<ScalarIntExpr>>(x.t));
peter klausler79d044e2018-03-01 00:56:10342 }
peter klausler8ea4a0a2018-04-06 20:13:20343 void Unparse(const ArrayConstructor &x) { // R769
peter klausler79d044e2018-03-01 00:56:10344 Put('['), Walk(x.v), Put(']');
peter klausler79d044e2018-03-01 00:56:10345 }
peter klausler8ea4a0a2018-04-06 20:13:20346 void Unparse(const AcSpec &x) { // R770
peter klausler79d044e2018-03-01 00:56:10347 Walk(x.type, "::"), Walk(x.values, ", ");
peter klausler79d044e2018-03-01 00:56:10348 }
peter klausler8ea4a0a2018-04-06 20:13:20349 template<typename A> void Unparse(const LoopBounds<A> &x) {
peter klausler79d044e2018-03-01 00:56:10350 Walk(x.name), Put('='), Walk(x.lower), Put(','), Walk(x.upper);
351 Walk(",", x.step);
peter klausler79d044e2018-03-01 00:56:10352 }
peter klausler8ea4a0a2018-04-06 20:13:20353 void Unparse(const AcImpliedDo &x) { // R774
peter klausler46c35382018-03-14 00:11:26354 Put('('), Walk(std::get<std::list<AcValue>>(x.t), ", ");
355 Put(", "), Walk(std::get<AcImpliedDoControl>(x.t)), Put(')');
peter klausler46c35382018-03-14 00:11:26356 }
peter klausler8ea4a0a2018-04-06 20:13:20357 void Unparse(const AcImpliedDoControl &x) { // R775
peter klausler79d044e2018-03-01 00:56:10358 Walk(std::get<std::optional<IntegerTypeSpec>>(x.t), "::");
359 Walk(std::get<LoopBounds<ScalarIntExpr>>(x.t));
Tim Keith2af29bc2018-02-26 22:28:32360 }
361
peter klausler8ea4a0a2018-04-06 20:13:20362 void Unparse(const TypeDeclarationStmt &x) { // R801
peter klausler79d044e2018-03-01 00:56:10363 const auto &dts = std::get<DeclarationTypeSpec>(x.t);
364 const auto &attrs = std::get<std::list<AttrSpec>>(x.t);
365 const auto &decls = std::get<std::list<EntityDecl>>(x.t);
366 Walk(dts), Walk(", ", attrs, ", ");
peter klausler92bcb7ce2018-03-19 23:17:23367
368 static const auto isInitializerOldStyle = [](const Initialization &i) {
369 return std::holds_alternative<std::list<Indirection<DataStmtValue>>>(i.u);
370 };
371 static const auto hasAssignmentInitializer = [](const EntityDecl &d) {
372 // Does a declaration have a new-style =x initializer?
373 const auto &init = std::get<std::optional<Initialization>>(d.t);
374 return init.has_value() && !isInitializerOldStyle(*init);
375 };
376 static const auto hasSlashDelimitedInitializer = [](const EntityDecl &d) {
377 // Does a declaration have an old-style /x/ initializer?
378 const auto &init = std::get<std::optional<Initialization>>(d.t);
379 return init.has_value() && isInitializerOldStyle(*init);
380 };
381 const auto useDoubledColons = [&]() {
382 bool isRecord{std::holds_alternative<DeclarationTypeSpec::Record>(dts.u)};
383 if (!attrs.empty()) {
384 // Attributes after the type require :: before the entities.
385 CHECK(!isRecord);
386 return true;
387 }
388 if (std::any_of(decls.begin(), decls.end(), hasAssignmentInitializer)) {
389 // Always use :: with new style standard initializers (=x),
390 // since the standard requires them to appear (even in free form,
391 // where mandatory spaces already disambiguate INTEGER J=666).
392 CHECK(!isRecord);
393 return true;
394 }
395 if (isRecord) {
396 // Never put :: in a legacy extension RECORD// statement.
397 return false;
398 }
399 // The :: is optional for this declaration. Avoid usage that can
400 // crash the pgf90 compiler.
401 if (std::any_of(
402 decls.begin(), decls.end(), hasSlashDelimitedInitializer)) {
403 // Don't use :: when a declaration uses legacy DATA-statement-like
404 // /x/ initialization.
405 return false;
406 }
407 // Don't use :: with intrinsic types. Otherwise, use it.
408 return !std::holds_alternative<IntrinsicTypeSpec>(dts.u);
409 };
410
411 if (useDoubledColons()) {
412 Put(" ::");
Tim Keith2af29bc2018-02-26 22:28:32413 }
peter klausler79d044e2018-03-01 00:56:10414 Put(' '), Walk(std::get<std::list<EntityDecl>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:10415 }
peter klausler8ea4a0a2018-04-06 20:13:20416 void Before(const AttrSpec &x) { // R802
peter klauslerb7cf5122018-03-14 22:31:16417 std::visit(visitors{[&](const CoarraySpec &y) { Word("CODIMENSION["); },
418 [&](const ArraySpec &y) { Word("DIMENSION("); },
peter klauslerd71f3cf2018-03-14 23:31:41419 [](const auto &) {}},
peter klauslerd39a33f2018-03-13 23:59:30420 x.u);
peter klauslerd39a33f2018-03-13 23:59:30421 }
422 void Post(const AttrSpec &x) {
423 std::visit(visitors{[&](const CoarraySpec &y) { Put(']'); },
peter klauslerd71f3cf2018-03-14 23:31:41424 [&](const ArraySpec &y) { Put(')'); }, [](const auto &) {}},
peter klauslerd39a33f2018-03-13 23:59:30425 x.u);
426 }
peter klausler8ea4a0a2018-04-06 20:13:20427 void Unparse(const EntityDecl &x) { // R803
peter klausler79d044e2018-03-01 00:56:10428 Walk(std::get<ObjectName>(x.t));
429 Walk("(", std::get<std::optional<ArraySpec>>(x.t), ")");
430 Walk("[", std::get<std::optional<CoarraySpec>>(x.t), "]");
431 Walk("*", std::get<std::optional<CharLength>>(x.t));
432 Walk(std::get<std::optional<Initialization>>(x.t));
peter klausler79d044e2018-03-01 00:56:10433 }
peter klausler8ea4a0a2018-04-06 20:13:20434 void Unparse(const NullInit &x) { // R806
peter klauslerb7cf5122018-03-14 22:31:16435 Word("NULL()");
peter klausler79d044e2018-03-01 00:56:10436 }
peter klausler8ea4a0a2018-04-06 20:13:20437 void Unparse(const LanguageBindingSpec &x) { // R808 & R1528
peter klauslerb7cf5122018-03-14 22:31:16438 Word("BIND(C"), Walk(", NAME=", x.v), Put(')');
peter klausler79d044e2018-03-01 00:56:10439 }
peter klausler8ea4a0a2018-04-06 20:13:20440 void Unparse(const CoarraySpec &x) { // R809
peter klausler79d044e2018-03-01 00:56:10441 std::visit(visitors{[&](const DeferredCoshapeSpecList &y) { Walk(y); },
442 [&](const ExplicitCoshapeSpec &y) { Walk(y); }},
443 x.u);
peter klausler79d044e2018-03-01 00:56:10444 }
peter klausler8ea4a0a2018-04-06 20:13:20445 void Unparse(const DeferredCoshapeSpecList &x) { // R810
peter klausler79d044e2018-03-01 00:56:10446 for (auto j = x.v; j > 0; --j) {
447 Put(':');
448 if (j > 1) {
449 Put(',');
Tim Keith2af29bc2018-02-26 22:28:32450 }
451 }
Tim Keith2af29bc2018-02-26 22:28:32452 }
peter klausler8ea4a0a2018-04-06 20:13:20453 void Unparse(const ExplicitCoshapeSpec &x) { // R811
peter klausler79d044e2018-03-01 00:56:10454 Walk(std::get<std::list<ExplicitShapeSpec>>(x.t), ",", ",");
455 Walk(std::get<std::optional<SpecificationExpr>>(x.t), ":"), Put('*');
Tim Keith2af29bc2018-02-26 22:28:32456 }
peter klausler8ea4a0a2018-04-06 20:13:20457 void Unparse(const ExplicitShapeSpec &x) { // R812 - R813 & R816 - R818
peter klausler79d044e2018-03-01 00:56:10458 Walk(std::get<std::optional<SpecificationExpr>>(x.t), ":");
459 Walk(std::get<SpecificationExpr>(x.t));
peter klausler79d044e2018-03-01 00:56:10460 }
peter klausler8ea4a0a2018-04-06 20:13:20461 void Unparse(const ArraySpec &x) { // R815
peter klausler79d044e2018-03-01 00:56:10462 std::visit(
463 visitors{[&](const std::list<ExplicitShapeSpec> &y) { Walk(y, ","); },
464 [&](const std::list<AssumedShapeSpec> &y) { Walk(y, ","); },
465 [&](const DeferredShapeSpecList &y) { Walk(y); },
466 [&](const AssumedSizeSpec &y) { Walk(y); },
467 [&](const ImpliedShapeSpec &y) { Walk(y); },
468 [&](const AssumedRankSpec &y) { Walk(y); }},
469 x.u);
peter klausler79d044e2018-03-01 00:56:10470 }
471 void Post(const AssumedShapeSpec &) { Put(':'); } // R819
peter klausler8ea4a0a2018-04-06 20:13:20472 void Unparse(const DeferredShapeSpecList &x) { // R820
peter klausler79d044e2018-03-01 00:56:10473 for (auto j = x.v; j > 0; --j) {
474 Put(':');
475 if (j > 1) {
476 Put(',');
477 }
478 }
peter klausler79d044e2018-03-01 00:56:10479 }
peter klausler8ea4a0a2018-04-06 20:13:20480 void Unparse(const AssumedImpliedSpec &x) { // R821
peter klausler79d044e2018-03-01 00:56:10481 Walk(x.v, ":");
482 Put('*');
peter klausler79d044e2018-03-01 00:56:10483 }
peter klausler8ea4a0a2018-04-06 20:13:20484 void Unparse(const AssumedSizeSpec &x) { // R822
peter klausler79d044e2018-03-01 00:56:10485 Walk(std::get<std::list<ExplicitShapeSpec>>(x.t), ",", ",");
486 Walk(std::get<AssumedImpliedSpec>(x.t));
peter klausler79d044e2018-03-01 00:56:10487 }
peter klausler8ea4a0a2018-04-06 20:13:20488 void Unparse(const ImpliedShapeSpec &x) { // R823
peter klausler79d044e2018-03-01 00:56:10489 Walk(x.v, ",");
peter klausler79d044e2018-03-01 00:56:10490 }
491 void Post(const AssumedRankSpec &) { Put(".."); } // R825
peter klauslerb7cf5122018-03-14 22:31:16492 void Post(const Asynchronous &) { Word("ASYNCHRONOUS"); }
493 void Post(const External &) { Word("EXTERNAL"); }
494 void Post(const Intrinsic &) { Word("INTRINSIC"); }
495 void Post(const Optional &) { Word("OPTIONAL"); }
496 void Post(const Parameter &) { Word("PARAMETER"); }
497 void Post(const Protected &) { Word("PROTECTED"); }
498 void Post(const Save &) { Word("SAVE"); }
499 void Post(const Target &) { Word("TARGET"); }
500 void Post(const Value &) { Word("VALUE"); }
501 void Post(const Volatile &) { Word("VOLATILE"); }
peter klausler8ea4a0a2018-04-06 20:13:20502 void Unparse(const IntentSpec &x) { // R826
peter klauslerb7cf5122018-03-14 22:31:16503 Word("INTENT("), Walk(x.v), Put(")");
peter klausler79d044e2018-03-01 00:56:10504 }
peter klausler8ea4a0a2018-04-06 20:13:20505 void Unparse(const AccessStmt &x) { // R827
peter klausler79d044e2018-03-01 00:56:10506 Walk(std::get<AccessSpec>(x.t));
507 Walk(" :: ", std::get<std::list<AccessId>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:10508 }
peter klausler8ea4a0a2018-04-06 20:13:20509 void Unparse(const AllocatableStmt &x) { // R829
peter klauslerb7cf5122018-03-14 22:31:16510 Word("ALLOCATABLE :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10511 }
peter klausler8ea4a0a2018-04-06 20:13:20512 void Unparse(const ObjectDecl &x) { // R830 & R860
peter klausler79d044e2018-03-01 00:56:10513 Walk(std::get<ObjectName>(x.t));
514 Walk("(", std::get<std::optional<ArraySpec>>(x.t), ")");
515 Walk("[", std::get<std::optional<CoarraySpec>>(x.t), "]");
peter klausler79d044e2018-03-01 00:56:10516 }
peter klausler8ea4a0a2018-04-06 20:13:20517 void Unparse(const AsynchronousStmt &x) { // R831
peter klauslerb7cf5122018-03-14 22:31:16518 Word("ASYNCHRONOUS :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10519 }
peter klausler8ea4a0a2018-04-06 20:13:20520 void Unparse(const BindStmt &x) { // R832
peter klausler79d044e2018-03-01 00:56:10521 Walk(x.t, " :: ");
peter klausler79d044e2018-03-01 00:56:10522 }
peter klausler8ea4a0a2018-04-06 20:13:20523 void Unparse(const BindEntity &x) { // R833
peter klausler79d044e2018-03-01 00:56:10524 bool isCommon{std::get<BindEntity::Kind>(x.t) == BindEntity::Kind::Common};
525 const char *slash{isCommon ? "/" : ""};
526 Put(slash), Walk(std::get<Name>(x.t)), Put(slash);
peter klausler79d044e2018-03-01 00:56:10527 }
peter klausler8ea4a0a2018-04-06 20:13:20528 void Unparse(const CodimensionStmt &x) { // R834
peter klauslerb7cf5122018-03-14 22:31:16529 Word("CODIMENSION :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10530 }
peter klausler8ea4a0a2018-04-06 20:13:20531 void Unparse(const CodimensionDecl &x) { // R835
peter klausler79d044e2018-03-01 00:56:10532 Walk(std::get<Name>(x.t));
533 Put('['), Walk(std::get<CoarraySpec>(x.t)), Put(']');
peter klausler79d044e2018-03-01 00:56:10534 }
peter klausler8ea4a0a2018-04-06 20:13:20535 void Unparse(const ContiguousStmt &x) { // R836
peter klauslerb7cf5122018-03-14 22:31:16536 Word("CONTIGUOUS :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10537 }
peter klausler8ea4a0a2018-04-06 20:13:20538 void Unparse(const DataStmt &x) { // R837
peter klauslerb7cf5122018-03-14 22:31:16539 Word("DATA "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10540 }
peter klausler8ea4a0a2018-04-06 20:13:20541 void Unparse(const DataStmtSet &x) { // R838
peter klausler79d044e2018-03-01 00:56:10542 Walk(std::get<std::list<DataStmtObject>>(x.t), ", ");
543 Put('/'), Walk(std::get<std::list<DataStmtValue>>(x.t), ", "), Put('/');
peter klausler79d044e2018-03-01 00:56:10544 }
peter klausler8ea4a0a2018-04-06 20:13:20545 void Unparse(const DataImpliedDo &x) { // R840, R842
peter klauslerb7cf5122018-03-14 22:31:16546 Put('('), Walk(std::get<std::list<DataIDoObject>>(x.t), ", "), Put(',');
peter klausler79d044e2018-03-01 00:56:10547 Walk(std::get<std::optional<IntegerTypeSpec>>(x.t), "::");
548 Walk(std::get<LoopBounds<ScalarIntConstantExpr>>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:10549 }
peter klausler8ea4a0a2018-04-06 20:13:20550 void Unparse(const DataStmtValue &x) { // R843
peter klausler79d044e2018-03-01 00:56:10551 Walk(std::get<std::optional<DataStmtRepeat>>(x.t), "*");
552 Walk(std::get<DataStmtConstant>(x.t));
peter klausler79d044e2018-03-01 00:56:10553 }
peter klausler8ea4a0a2018-04-06 20:13:20554 void Unparse(const DimensionStmt &x) { // R848
peter klauslerb7cf5122018-03-14 22:31:16555 Word("DIMENSION :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10556 }
peter klausler8ea4a0a2018-04-06 20:13:20557 void Unparse(const DimensionStmt::Declaration &x) {
peter klausler79d044e2018-03-01 00:56:10558 Walk(std::get<Name>(x.t));
559 Put('('), Walk(std::get<ArraySpec>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:10560 }
peter klausler8ea4a0a2018-04-06 20:13:20561 void Unparse(const IntentStmt &x) { // R849
peter klausler79d044e2018-03-01 00:56:10562 Walk(x.t, " :: ");
peter klausler79d044e2018-03-01 00:56:10563 }
peter klausler8ea4a0a2018-04-06 20:13:20564 void Unparse(const OptionalStmt &x) { // R850
peter klauslerb7cf5122018-03-14 22:31:16565 Word("OPTIONAL :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10566 }
peter klausler8ea4a0a2018-04-06 20:13:20567 void Unparse(const ParameterStmt &x) { // R851
peter klauslerb7cf5122018-03-14 22:31:16568 Word("PARAMETER("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10569 }
peter klausler8ea4a0a2018-04-06 20:13:20570 void Unparse(const NamedConstantDef &x) { // R852
peter klausler79d044e2018-03-01 00:56:10571 Walk(x.t, "=");
peter klausler79d044e2018-03-01 00:56:10572 }
peter klausler8ea4a0a2018-04-06 20:13:20573 void Unparse(const PointerStmt &x) { // R853
peter klausler26b5f572018-04-09 20:40:20574 Word("POINTER :: "), Walk(x.v, ", ");
575 }
576 void Unparse(const PointerDecl &x) { // R854
577 Walk(std::get<Name>(x.t));
578 Walk("(", std::get<std::optional<DeferredShapeSpecList>>(x.t), ")");
peter klausler79d044e2018-03-01 00:56:10579 }
peter klausler8ea4a0a2018-04-06 20:13:20580 void Unparse(const ProtectedStmt &x) { // R855
peter klauslerb7cf5122018-03-14 22:31:16581 Word("PROTECTED :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10582 }
peter klausler8ea4a0a2018-04-06 20:13:20583 void Unparse(const SaveStmt &x) { // R856
peter klauslerb7cf5122018-03-14 22:31:16584 Word("SAVE"), Walk(" :: ", x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10585 }
peter klausler8ea4a0a2018-04-06 20:13:20586 void Unparse(const SavedEntity &x) { // R857, R858
peter klausler79d044e2018-03-01 00:56:10587 bool isCommon{
588 std::get<SavedEntity::Kind>(x.t) == SavedEntity::Kind::Common};
589 const char *slash{isCommon ? "/" : ""};
590 Put(slash), Walk(std::get<Name>(x.t)), Put(slash);
peter klausler79d044e2018-03-01 00:56:10591 }
peter klausler8ea4a0a2018-04-06 20:13:20592 void Unparse(const TargetStmt &x) { // R859
peter klauslerb7cf5122018-03-14 22:31:16593 Word("TARGET :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10594 }
peter klausler8ea4a0a2018-04-06 20:13:20595 void Unparse(const ValueStmt &x) { // R861
peter klauslerb7cf5122018-03-14 22:31:16596 Word("VALUE :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10597 }
peter klausler8ea4a0a2018-04-06 20:13:20598 void Unparse(const VolatileStmt &x) { // R862
peter klauslerb7cf5122018-03-14 22:31:16599 Word("VOLATILE :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10600 }
peter klausler8ea4a0a2018-04-06 20:13:20601 void Unparse(const ImplicitStmt &x) { // R863
peter klauslerb7cf5122018-03-14 22:31:16602 Word("IMPLICIT ");
peter klausler79d044e2018-03-01 00:56:10603 std::visit(
604 visitors{[&](const std::list<ImplicitSpec> &y) { Walk(y, ", "); },
605 [&](const std::list<ImplicitStmt::ImplicitNoneNameSpec> &y) {
peter klauslerb7cf5122018-03-14 22:31:16606 Word("NONE"), Walk(" (", y, ", ", ")");
peter klausler79d044e2018-03-01 00:56:10607 }},
608 x.u);
peter klausler79d044e2018-03-01 00:56:10609 }
peter klausler8ea4a0a2018-04-06 20:13:20610 void Unparse(const ImplicitSpec &x) { // R864
peter klausler79d044e2018-03-01 00:56:10611 Walk(std::get<DeclarationTypeSpec>(x.t));
612 Put('('), Walk(std::get<std::list<LetterSpec>>(x.t), ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10613 }
peter klausler8ea4a0a2018-04-06 20:13:20614 void Unparse(const LetterSpec &x) { // R865
peter klausler424ec7b2018-03-20 17:59:07615 Put(*std::get<const char *>(x.t));
616 auto second = std::get<std::optional<const char *>>(x.t);
617 if (second.has_value()) {
618 Put('-'), Put(**second);
619 }
peter klausler79d044e2018-03-01 00:56:10620 }
peter klausler8ea4a0a2018-04-06 20:13:20621 void Unparse(const ImportStmt &x) { // R867
peter klauslerb7cf5122018-03-14 22:31:16622 Word("IMPORT");
peter klausler79d044e2018-03-01 00:56:10623 switch (x.kind) {
peter klausler2e5300c2018-03-15 23:22:38624 case ImportStmt::Kind::Default: Walk(" :: ", x.names, ", "); break;
peter klausler79d044e2018-03-01 00:56:10625 case ImportStmt::Kind::Only:
peter klauslerb7cf5122018-03-14 22:31:16626 Put(", "), Word("ONLY: ");
peter klauslerdcd09422018-03-15 23:03:28627 Walk(x.names, ", ");
peter klausler79d044e2018-03-01 00:56:10628 break;
peter klauslerb7cf5122018-03-14 22:31:16629 case ImportStmt::Kind::None: Word(", NONE"); break;
630 case ImportStmt::Kind::All: Word(", ALL"); break;
peter klausler79d044e2018-03-01 00:56:10631 default: CRASH_NO_CASE;
632 }
peter klausler79d044e2018-03-01 00:56:10633 }
peter klausler8ea4a0a2018-04-06 20:13:20634 void Unparse(const NamelistStmt &x) { // R868
peter klauslerb7cf5122018-03-14 22:31:16635 Word("NAMELIST"), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:10636 }
peter klausler8ea4a0a2018-04-06 20:13:20637 void Unparse(const NamelistStmt::Group &x) {
peter klausler424ec7b2018-03-20 17:59:07638 Put('/'), Walk(std::get<Name>(x.t)), Put('/');
peter klausler79d044e2018-03-01 00:56:10639 Walk(std::get<std::list<Name>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:10640 }
peter klausler8ea4a0a2018-04-06 20:13:20641 void Unparse(const EquivalenceStmt &x) { // R870, R871
peter klauslerb7cf5122018-03-14 22:31:16642 Word("EQUIVALENCE");
peter klausler79d044e2018-03-01 00:56:10643 const char *separator{" "};
644 for (const std::list<EquivalenceObject> &y : x.v) {
645 Put(separator), Put('('), Walk(y), Put(')');
646 separator = ", ";
647 }
peter klausler79d044e2018-03-01 00:56:10648 }
peter klausler8ea4a0a2018-04-06 20:13:20649 void Unparse(const CommonStmt &x) { // R873
peter klauslerb7cf5122018-03-14 22:31:16650 Word("COMMON ");
peter klausler66c98ee2018-04-24 22:46:16651 Walk("/", std::get<std::optional<Name>>(x.t), "/");
peter klausler79d044e2018-03-01 00:56:10652 Walk(std::get<std::list<CommonBlockObject>>(x.t), ", ");
653 Walk(", ", std::get<std::list<CommonStmt::Block>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:10654 }
peter klausler8ea4a0a2018-04-06 20:13:20655 void Unparse(const CommonBlockObject &x) { // R874
peter klausler79d044e2018-03-01 00:56:10656 Walk(std::get<Name>(x.t));
657 Walk("(", std::get<std::optional<ArraySpec>>(x.t), ")");
peter klausler79d044e2018-03-01 00:56:10658 }
peter klausler8ea4a0a2018-04-06 20:13:20659 void Unparse(const CommonStmt::Block &x) {
peter klausler79d044e2018-03-01 00:56:10660 Walk("/", std::get<std::optional<Name>>(x.t), "/");
661 Walk(std::get<std::list<CommonBlockObject>>(x.t));
peter klausler79d044e2018-03-01 00:56:10662 }
Tim Keith2af29bc2018-02-26 22:28:32663
peter klausler8ea4a0a2018-04-06 20:13:20664 void Unparse(const Substring &x) { // R908, R909
peter klausler2884b2e2018-04-13 21:21:13665 Walk(std::get<DataRef>(x.t));
peter klausler79d044e2018-03-01 00:56:10666 Put('('), Walk(std::get<SubstringRange>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:10667 }
peter klausler8ea4a0a2018-04-06 20:13:20668 void Unparse(const CharLiteralConstantSubstring &x) {
peter klausler79d044e2018-03-01 00:56:10669 Walk(std::get<CharLiteralConstant>(x.t));
670 Put('('), Walk(std::get<SubstringRange>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:10671 }
peter klausler8ea4a0a2018-04-06 20:13:20672 void Unparse(const SubstringRange &x) { // R910
peter klausler79d044e2018-03-01 00:56:10673 Walk(x.t, ":");
peter klausler79d044e2018-03-01 00:56:10674 }
peter klausler8ea4a0a2018-04-06 20:13:20675 void Unparse(const PartRef &x) { // R912
peter klausler79d044e2018-03-01 00:56:10676 Walk(x.name);
677 Walk("(", x.subscripts, ",", ")");
678 Walk(x.imageSelector);
peter klausler79d044e2018-03-01 00:56:10679 }
peter klausler8ea4a0a2018-04-06 20:13:20680 void Unparse(const StructureComponent &x) { // R913
peter klausler4e354d82018-03-30 22:23:37681 Walk(x.base);
682 if (structureComponents_.find(x.component.source) !=
683 structureComponents_.end()) {
684 Put('.');
685 } else {
686 Put('%');
687 }
688 Walk(x.component);
peter klausler79d044e2018-03-01 00:56:10689 }
peter klausler8ea4a0a2018-04-06 20:13:20690 void Unparse(const ArrayElement &x) { // R917
peter klausler79d044e2018-03-01 00:56:10691 Walk(x.base);
692 Put('('), Walk(x.subscripts, ","), Put(')');
peter klausler79d044e2018-03-01 00:56:10693 }
peter klausler8ea4a0a2018-04-06 20:13:20694 void Unparse(const SubscriptTriplet &x) { // R921
peter klausler79d044e2018-03-01 00:56:10695 Walk(std::get<0>(x.t)), Put(':'), Walk(std::get<1>(x.t));
696 Walk(":", std::get<2>(x.t));
peter klausler79d044e2018-03-01 00:56:10697 }
peter klausler8ea4a0a2018-04-06 20:13:20698 void Unparse(const ImageSelector &x) { // R924
peter klausler79d044e2018-03-01 00:56:10699 Put('['), Walk(std::get<std::list<Cosubscript>>(x.t), ",");
700 Walk(",", std::get<std::list<ImageSelectorSpec>>(x.t), ","), Put(']');
peter klausler79d044e2018-03-01 00:56:10701 }
peter klausler8ea4a0a2018-04-06 20:13:20702 void Before(const ImageSelectorSpec::Stat &) { // R926
peter klauslerb7cf5122018-03-14 22:31:16703 Word("STAT=");
peter klausler79d044e2018-03-01 00:56:10704 }
peter klausler8ea4a0a2018-04-06 20:13:20705 void Before(const ImageSelectorSpec::Team &) { Word("TEAM="); }
706 void Before(const ImageSelectorSpec::Team_Number &) { Word("TEAM_NUMBER="); }
707 void Unparse(const AllocateStmt &x) { // R927
peter klauslerb7cf5122018-03-14 22:31:16708 Word("ALLOCATE(");
709 Walk(std::get<std::optional<TypeSpec>>(x.t), "::");
peter klausler79d044e2018-03-01 00:56:10710 Walk(std::get<std::list<Allocation>>(x.t), ", ");
711 Walk(", ", std::get<std::list<AllocOpt>>(x.t), ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10712 }
peter klausler8ea4a0a2018-04-06 20:13:20713 void Before(const AllocOpt &x) { // R928, R931
peter klauslerb7cf5122018-03-14 22:31:16714 std::visit(visitors{[&](const AllocOpt::Mold &) { Word("MOLD="); },
715 [&](const AllocOpt::Source &) { Word("SOURCE="); },
peter klauslered5a6c92018-03-15 00:07:15716 [](const StatOrErrmsg &) {}},
peter klausler79d044e2018-03-01 00:56:10717 x.u);
peter klausler79d044e2018-03-01 00:56:10718 }
peter klausler8ea4a0a2018-04-06 20:13:20719 void Unparse(const Allocation &x) { // R932
peter klausler79d044e2018-03-01 00:56:10720 Walk(std::get<AllocateObject>(x.t));
721 Walk("(", std::get<std::list<AllocateShapeSpec>>(x.t), ",", ")");
722 Walk("[", std::get<std::optional<AllocateCoarraySpec>>(x.t), "]");
peter klausler79d044e2018-03-01 00:56:10723 }
peter klausler8ea4a0a2018-04-06 20:13:20724 void Unparse(const AllocateShapeSpec &x) { // R934 & R938
peter klausler79d044e2018-03-01 00:56:10725 Walk(std::get<std::optional<BoundExpr>>(x.t), ":");
726 Walk(std::get<BoundExpr>(x.t));
peter klausler79d044e2018-03-01 00:56:10727 }
peter klausler8ea4a0a2018-04-06 20:13:20728 void Unparse(const AllocateCoarraySpec &x) { // R937
peter klausler79d044e2018-03-01 00:56:10729 Walk(std::get<std::list<AllocateCoshapeSpec>>(x.t), ",", ",");
730 Walk(std::get<std::optional<BoundExpr>>(x.t), ":"), Put('*');
peter klausler79d044e2018-03-01 00:56:10731 }
peter klausler8ea4a0a2018-04-06 20:13:20732 void Unparse(const NullifyStmt &x) { // R939
peter klauslerb7cf5122018-03-14 22:31:16733 Word("NULLIFY("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10734 }
peter klausler8ea4a0a2018-04-06 20:13:20735 void Unparse(const DeallocateStmt &x) { // R941
peter klauslerb7cf5122018-03-14 22:31:16736 Word("DEALLOCATE(");
737 Walk(std::get<std::list<AllocateObject>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:10738 Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10739 }
peter klausler8ea4a0a2018-04-06 20:13:20740 void Before(const StatOrErrmsg &x) { // R942 & R1165
peter klauslerb7cf5122018-03-14 22:31:16741 std::visit(visitors{[&](const StatVariable &) { Word("STAT="); },
742 [&](const MsgVariable &) { Word("ERRMSG="); }},
peter klausler79d044e2018-03-01 00:56:10743 x.u);
peter klausler79d044e2018-03-01 00:56:10744 }
745
746 // R1001 - R1022
peter klausler8ea4a0a2018-04-06 20:13:20747 void Unparse(const Expr::Parentheses &x) { Put('('), Walk(x.v), Put(')'); }
748 void Before(const Expr::UnaryPlus &x) { Put("+"); }
749 void Before(const Expr::Negate &x) { Put("-"); }
750 void Before(const Expr::NOT &x) { Word(".NOT."); }
751 void Unparse(const Expr::PercentLoc &x) {
peter klauslerb7cf5122018-03-14 22:31:16752 Word("%LOC("), Walk(x.v), Put(')');
peter klausler79d044e2018-03-01 00:56:10753 }
peter klausler8ea4a0a2018-04-06 20:13:20754 void Unparse(const Expr::Power &x) { Walk(x.t, "**"); }
755 void Unparse(const Expr::Multiply &x) { Walk(x.t, "*"); }
756 void Unparse(const Expr::Divide &x) { Walk(x.t, "/"); }
757 void Unparse(const Expr::Add &x) { Walk(x.t, "+"); }
758 void Unparse(const Expr::Subtract &x) { Walk(x.t, "-"); }
759 void Unparse(const Expr::Concat &x) { Walk(x.t, "//"); }
760 void Unparse(const Expr::LT &x) { Walk(x.t, "<"); }
761 void Unparse(const Expr::LE &x) { Walk(x.t, "<="); }
762 void Unparse(const Expr::EQ &x) { Walk(x.t, "=="); }
763 void Unparse(const Expr::NE &x) { Walk(x.t, "/="); }
764 void Unparse(const Expr::GE &x) { Walk(x.t, ">="); }
765 void Unparse(const Expr::GT &x) { Walk(x.t, ">"); }
766 void Unparse(const Expr::AND &x) { Walk(x.t, ".AND."); }
767 void Unparse(const Expr::OR &x) { Walk(x.t, ".OR."); }
768 void Unparse(const Expr::EQV &x) { Walk(x.t, ".EQV."); }
769 void Unparse(const Expr::NEQV &x) { Walk(x.t, ".NEQV."); }
770 void Unparse(const Expr::XOR &x) { Walk(x.t, ".XOR."); }
771 void Unparse(const Expr::ComplexConstructor &x) {
peter klausler79d044e2018-03-01 00:56:10772 Put('('), Walk(x.t, ","), Put(')');
peter klausler79d044e2018-03-01 00:56:10773 }
peter klausler8ea4a0a2018-04-06 20:13:20774 void Unparse(const Expr::DefinedBinary &x) {
peter klausler79d044e2018-03-01 00:56:10775 Walk(std::get<1>(x.t)); // left
776 Walk(std::get<DefinedOpName>(x.t));
777 Walk(std::get<2>(x.t)); // right
peter klausler79d044e2018-03-01 00:56:10778 }
peter klausler8ea4a0a2018-04-06 20:13:20779 void Unparse(const DefinedOpName &x) { // R1003, R1023, R1414, & R1415
peter klausler424ec7b2018-03-20 17:59:07780 Put('.'), Walk(x.v), Put('.');
peter klausler79d044e2018-03-01 00:56:10781 }
peter klausler8ea4a0a2018-04-06 20:13:20782 void Unparse(const AssignmentStmt &x) { // R1032
peter klausler79d044e2018-03-01 00:56:10783 Walk(x.t, " = ");
peter klausler79d044e2018-03-01 00:56:10784 }
peter klausler8ea4a0a2018-04-06 20:13:20785 void Unparse(const PointerAssignmentStmt &x) { // R1033, R1034, R1038
peter klausler2884b2e2018-04-13 21:21:13786 Walk(std::get<DataRef>(x.t));
peter klausler79d044e2018-03-01 00:56:10787 std::visit(
788 visitors{[&](const std::list<BoundsRemapping> &y) {
789 Put('('), Walk(y), Put(')');
790 },
791 [&](const std::list<BoundsSpec> &y) { Walk("(", y, ", ", ")"); }},
792 std::get<PointerAssignmentStmt::Bounds>(x.t).u);
793 Put(" => "), Walk(std::get<Expr>(x.t));
peter klausler79d044e2018-03-01 00:56:10794 }
795 void Post(const BoundsSpec &) { // R1035
796 Put(':');
797 }
peter klausler8ea4a0a2018-04-06 20:13:20798 void Unparse(const BoundsRemapping &x) { // R1036
peter klausler79d044e2018-03-01 00:56:10799 Walk(x.t, ":");
peter klausler79d044e2018-03-01 00:56:10800 }
peter klausler8ea4a0a2018-04-06 20:13:20801 void Unparse(const WhereStmt &x) { // R1041, R1045, R1046
peter klauslerb7cf5122018-03-14 22:31:16802 Word("WHERE ("), Walk(x.t, ") ");
peter klausler79d044e2018-03-01 00:56:10803 }
peter klausler8ea4a0a2018-04-06 20:13:20804 void Unparse(const WhereConstructStmt &x) { // R1043
peter klausler79d044e2018-03-01 00:56:10805 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16806 Word("WHERE ("), Walk(std::get<LogicalExpr>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:10807 Indent();
peter klausler79d044e2018-03-01 00:56:10808 }
peter klausler8ea4a0a2018-04-06 20:13:20809 void Unparse(const MaskedElsewhereStmt &x) { // R1047
peter klausler79d044e2018-03-01 00:56:10810 Outdent();
peter klauslerb7cf5122018-03-14 22:31:16811 Word("ELSEWHERE ("), Walk(std::get<LogicalExpr>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:10812 Walk(" ", std::get<std::optional<Name>>(x.t));
813 Indent();
peter klausler79d044e2018-03-01 00:56:10814 }
peter klausler8ea4a0a2018-04-06 20:13:20815 void Unparse(const ElsewhereStmt &x) { // R1048
peter klauslerb7cf5122018-03-14 22:31:16816 Outdent(), Word("ELSEWHERE"), Walk(" ", x.v), Indent();
peter klausler79d044e2018-03-01 00:56:10817 }
peter klausler8ea4a0a2018-04-06 20:13:20818 void Unparse(const EndWhereStmt &x) { // R1049
peter klauslerb7cf5122018-03-14 22:31:16819 Outdent(), Word("END WHERE"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10820 }
peter klausler8ea4a0a2018-04-06 20:13:20821 void Unparse(const ForallConstructStmt &x) { // R1051
peter klausler79d044e2018-03-01 00:56:10822 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16823 Word("FORALL"), Walk(std::get<Indirection<ConcurrentHeader>>(x.t));
peter klausler79d044e2018-03-01 00:56:10824 Indent();
peter klausler79d044e2018-03-01 00:56:10825 }
peter klausler8ea4a0a2018-04-06 20:13:20826 void Unparse(const EndForallStmt &x) { // R1054
peter klauslerb7cf5122018-03-14 22:31:16827 Outdent(), Word("END FORALL"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10828 }
peter klausler8ea4a0a2018-04-06 20:13:20829 void Before(const ForallStmt &) { // R1055
peter klauslerb7cf5122018-03-14 22:31:16830 Word("FORALL");
peter klausler79d044e2018-03-01 00:56:10831 }
832
peter klausler8ea4a0a2018-04-06 20:13:20833 void Unparse(const AssociateStmt &x) { // R1103
peter klausler79d044e2018-03-01 00:56:10834 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16835 Word("ASSOCIATE (");
836 Walk(std::get<std::list<Association>>(x.t), ", "), Put(')'), Indent();
peter klausler79d044e2018-03-01 00:56:10837 }
peter klausler8ea4a0a2018-04-06 20:13:20838 void Unparse(const Association &x) { // R1104
peter klausler79d044e2018-03-01 00:56:10839 Walk(x.t, " => ");
peter klausler79d044e2018-03-01 00:56:10840 }
peter klausler8ea4a0a2018-04-06 20:13:20841 void Unparse(const EndAssociateStmt &x) { // R1106
peter klauslerb7cf5122018-03-14 22:31:16842 Outdent(), Word("END ASSOCIATE"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10843 }
peter klausler8ea4a0a2018-04-06 20:13:20844 void Unparse(const BlockStmt &x) { // R1108
peter klauslerb7cf5122018-03-14 22:31:16845 Walk(x.v, ": "), Word("BLOCK"), Indent();
peter klausler79d044e2018-03-01 00:56:10846 }
peter klausler8ea4a0a2018-04-06 20:13:20847 void Unparse(const EndBlockStmt &x) { // R1110
peter klauslerb7cf5122018-03-14 22:31:16848 Outdent(), Word("END BLOCK"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10849 }
peter klausler8ea4a0a2018-04-06 20:13:20850 void Unparse(const ChangeTeamStmt &x) { // R1112
peter klausler79d044e2018-03-01 00:56:10851 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16852 Word("CHANGE TEAM ("), Walk(std::get<TeamVariable>(x.t));
peter klausler79d044e2018-03-01 00:56:10853 Walk(", ", std::get<std::list<CoarrayAssociation>>(x.t), ", ");
854 Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
855 Indent();
peter klausler79d044e2018-03-01 00:56:10856 }
peter klausler8ea4a0a2018-04-06 20:13:20857 void Unparse(const CoarrayAssociation &x) { // R1113
peter klausler79d044e2018-03-01 00:56:10858 Walk(x.t, " => ");
peter klausler79d044e2018-03-01 00:56:10859 }
peter klausler8ea4a0a2018-04-06 20:13:20860 void Unparse(const EndChangeTeamStmt &x) { // R1114
peter klauslerb7cf5122018-03-14 22:31:16861 Outdent(), Word("END TEAM (");
peter klausler79d044e2018-03-01 00:56:10862 Walk(std::get<std::list<StatOrErrmsg>>(x.t), ", ");
863 Put(')'), Walk(" ", std::get<std::optional<Name>>(x.t));
peter klausler79d044e2018-03-01 00:56:10864 }
peter klausler8ea4a0a2018-04-06 20:13:20865 void Unparse(const CriticalStmt &x) { // R1117
peter klausler79d044e2018-03-01 00:56:10866 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16867 Word("CRITICAL ("), Walk(std::get<std::list<StatOrErrmsg>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:10868 Put(')'), Indent();
peter klausler79d044e2018-03-01 00:56:10869 }
peter klausler8ea4a0a2018-04-06 20:13:20870 void Unparse(const EndCriticalStmt &x) { // R1118
peter klauslerb7cf5122018-03-14 22:31:16871 Outdent(), Word("END CRITICAL"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10872 }
peter klausler8ea4a0a2018-04-06 20:13:20873 void Unparse(const DoConstruct &x) { // R1119, R1120
peter klausler79d044e2018-03-01 00:56:10874 Walk(std::get<Statement<NonLabelDoStmt>>(x.t));
875 Indent(), Walk(std::get<Block>(x.t), ""), Outdent();
876 Walk(std::get<Statement<EndDoStmt>>(x.t));
peter klausler79d044e2018-03-01 00:56:10877 }
peter klausler8ea4a0a2018-04-06 20:13:20878 void Unparse(const LabelDoStmt &x) { // R1121
peter klausler79d044e2018-03-01 00:56:10879 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16880 Word("DO "), Walk(std::get<Label>(x.t));
peter klausler79d044e2018-03-01 00:56:10881 Walk(" ", std::get<std::optional<LoopControl>>(x.t));
peter klausler79d044e2018-03-01 00:56:10882 }
peter klausler8ea4a0a2018-04-06 20:13:20883 void Unparse(const NonLabelDoStmt &x) { // R1122
peter klausler79d044e2018-03-01 00:56:10884 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16885 Word("DO "), Walk(std::get<std::optional<LoopControl>>(x.t));
peter klausler79d044e2018-03-01 00:56:10886 }
peter klausler8ea4a0a2018-04-06 20:13:20887 void Unparse(const LoopControl &x) { // R1123
peter klausler79d044e2018-03-01 00:56:10888 std::visit(visitors{[&](const ScalarLogicalExpr &y) {
peter klauslerb7cf5122018-03-14 22:31:16889 Word("WHILE ("), Walk(y), Put(')');
peter klausler79d044e2018-03-01 00:56:10890 },
891 [&](const auto &y) { Walk(y); }},
892 x.u);
peter klausler79d044e2018-03-01 00:56:10893 }
peter klausler8ea4a0a2018-04-06 20:13:20894 void Unparse(const ConcurrentHeader &x) { // R1125
peter klausler79d044e2018-03-01 00:56:10895 Put('('), Walk(std::get<std::optional<IntegerTypeSpec>>(x.t), "::");
896 Walk(std::get<std::list<ConcurrentControl>>(x.t), ", ");
897 Walk(", ", std::get<std::optional<ScalarLogicalExpr>>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:10898 }
peter klausler8ea4a0a2018-04-06 20:13:20899 void Unparse(const ConcurrentControl &x) { // R1126 - R1128
peter klausler79d044e2018-03-01 00:56:10900 Walk(std::get<Name>(x.t)), Put('='), Walk(std::get<1>(x.t));
901 Put(':'), Walk(std::get<2>(x.t));
902 Walk(":", std::get<std::optional<ScalarIntExpr>>(x.t));
peter klausler79d044e2018-03-01 00:56:10903 }
peter klausler8ea4a0a2018-04-06 20:13:20904 void Before(const LoopControl::Concurrent &x) { // R1129
peter klauslerb7cf5122018-03-14 22:31:16905 Word("CONCURRENT");
peter klausler79d044e2018-03-01 00:56:10906 }
peter klausler8ea4a0a2018-04-06 20:13:20907 void Unparse(const LocalitySpec::Local &x) {
peter klauslerb7cf5122018-03-14 22:31:16908 Word("LOCAL("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10909 }
peter klausler8ea4a0a2018-04-06 20:13:20910 void Unparse(const LocalitySpec::LocalInit &x) {
peter klauslerb7cf5122018-03-14 22:31:16911 Word("LOCAL INIT("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10912 }
peter klausler8ea4a0a2018-04-06 20:13:20913 void Unparse(const LocalitySpec::Shared &x) {
peter klauslerb7cf5122018-03-14 22:31:16914 Word("SHARED("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:10915 }
peter klauslerb7cf5122018-03-14 22:31:16916 void Post(const LocalitySpec::DefaultNone &x) { Word("DEFAULT(NONE)"); }
peter klausler8ea4a0a2018-04-06 20:13:20917 void Unparse(const EndDoStmt &x) { // R1132
peter klauslerb7cf5122018-03-14 22:31:16918 Word("END DO"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10919 }
peter klausler8ea4a0a2018-04-06 20:13:20920 void Unparse(const CycleStmt &x) { // R1133
peter klauslerb7cf5122018-03-14 22:31:16921 Word("CYCLE"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10922 }
peter klausler8ea4a0a2018-04-06 20:13:20923 void Unparse(const IfThenStmt &x) { // R1135
peter klausler79d044e2018-03-01 00:56:10924 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16925 Word("IF ("), Walk(std::get<ScalarLogicalExpr>(x.t));
926 Put(") "), Word("THEN"), Indent();
peter klausler79d044e2018-03-01 00:56:10927 }
peter klausler8ea4a0a2018-04-06 20:13:20928 void Unparse(const ElseIfStmt &x) { // R1136
peter klauslerb7cf5122018-03-14 22:31:16929 Outdent(), Word("ELSE IF (");
930 Walk(std::get<ScalarLogicalExpr>(x.t)), Put(") "), Word("THEN");
931 Walk(" ", std::get<std::optional<Name>>(x.t)), Indent();
peter klausler79d044e2018-03-01 00:56:10932 }
peter klausler8ea4a0a2018-04-06 20:13:20933 void Unparse(const ElseStmt &x) { // R1137
peter klauslerb7cf5122018-03-14 22:31:16934 Outdent(), Word("ELSE"), Walk(" ", x.v), Indent();
peter klausler79d044e2018-03-01 00:56:10935 }
peter klausler8ea4a0a2018-04-06 20:13:20936 void Unparse(const EndIfStmt &x) { // R1138
peter klauslerb7cf5122018-03-14 22:31:16937 Outdent(), Word("END IF"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10938 }
peter klausler8ea4a0a2018-04-06 20:13:20939 void Unparse(const IfStmt &x) { // R1139
peter klauslerb7cf5122018-03-14 22:31:16940 Word("IF ("), Walk(x.t, ") ");
peter klausler79d044e2018-03-01 00:56:10941 }
peter klausler8ea4a0a2018-04-06 20:13:20942 void Unparse(const SelectCaseStmt &x) { // R1141, R1144
peter klausler79d044e2018-03-01 00:56:10943 Walk(std::get<std::optional<Name>>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16944 Word("SELECT CASE (");
945 Walk(std::get<Scalar<Expr>>(x.t)), Put(')'), Indent();
peter klausler79d044e2018-03-01 00:56:10946 }
peter klausler8ea4a0a2018-04-06 20:13:20947 void Unparse(const CaseStmt &x) { // R1142
peter klauslerb7cf5122018-03-14 22:31:16948 Outdent(), Word("CASE "), Walk(std::get<CaseSelector>(x.t));
peter klausler79d044e2018-03-01 00:56:10949 Walk(" ", std::get<std::optional<Name>>(x.t)), Indent();
peter klausler79d044e2018-03-01 00:56:10950 }
peter klausler8ea4a0a2018-04-06 20:13:20951 void Unparse(const EndSelectStmt &x) { // R1143 & R1151 & R1155
peter klauslerb7cf5122018-03-14 22:31:16952 Outdent(), Word("END SELECT"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:10953 }
peter klausler8ea4a0a2018-04-06 20:13:20954 void Unparse(const CaseSelector &x) { // R1145
peter klausler79d044e2018-03-01 00:56:10955 std::visit(visitors{[&](const std::list<CaseValueRange> &y) {
956 Put('('), Walk(y), Put(')');
957 },
peter klauslerb7cf5122018-03-14 22:31:16958 [&](const Default &) { Word("DEFAULT"); }},
peter klausler79d044e2018-03-01 00:56:10959 x.u);
peter klausler79d044e2018-03-01 00:56:10960 }
peter klausler8ea4a0a2018-04-06 20:13:20961 void Unparse(const CaseValueRange::Range &x) { // R1146
peter klausler79d044e2018-03-01 00:56:10962 Walk(x.lower), Put(':'), Walk(x.upper);
peter klausler79d044e2018-03-01 00:56:10963 }
peter klausler8ea4a0a2018-04-06 20:13:20964 void Unparse(const SelectRankStmt &x) { // R1149
peter klausler79d044e2018-03-01 00:56:10965 Walk(std::get<0>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16966 Word("SELECT RANK ("), Walk(std::get<1>(x.t), " => ");
peter klausler79d044e2018-03-01 00:56:10967 Walk(std::get<Selector>(x.t)), Put(')'), Indent();
peter klausler79d044e2018-03-01 00:56:10968 }
peter klausler8ea4a0a2018-04-06 20:13:20969 void Unparse(const SelectRankCaseStmt &x) { // R1150
peter klauslerb7cf5122018-03-14 22:31:16970 Outdent(), Word("RANK ");
peter klausler79d044e2018-03-01 00:56:10971 std::visit(visitors{[&](const ScalarIntConstantExpr &y) {
972 Put('('), Walk(y), Put(')');
973 },
974 [&](const Star &) { Put("(*)"); },
peter klauslerb7cf5122018-03-14 22:31:16975 [&](const Default &) { Word("DEFAULT"); }},
peter klausler79d044e2018-03-01 00:56:10976 std::get<SelectRankCaseStmt::Rank>(x.t).u);
977 Walk(" ", std::get<std::optional<Name>>(x.t)), Indent();
peter klausler79d044e2018-03-01 00:56:10978 }
peter klausler8ea4a0a2018-04-06 20:13:20979 void Unparse(const SelectTypeStmt &x) { // R1153
peter klausler79d044e2018-03-01 00:56:10980 Walk(std::get<0>(x.t), ": ");
peter klauslerb7cf5122018-03-14 22:31:16981 Word("SELECT TYPE ("), Walk(std::get<1>(x.t), " => ");
peter klausler79d044e2018-03-01 00:56:10982 Walk(std::get<Selector>(x.t)), Put(')'), Indent();
peter klausler79d044e2018-03-01 00:56:10983 }
peter klausler8ea4a0a2018-04-06 20:13:20984 void Unparse(const TypeGuardStmt &x) { // R1154
peter klausler79d044e2018-03-01 00:56:10985 Outdent(), Walk(std::get<TypeGuardStmt::Guard>(x.t));
986 Walk(" ", std::get<std::optional<Name>>(x.t)), Indent();
peter klausler79d044e2018-03-01 00:56:10987 }
peter klausler8ea4a0a2018-04-06 20:13:20988 void Unparse(const TypeGuardStmt::Guard &x) {
peter klausler79d044e2018-03-01 00:56:10989 std::visit(visitors{[&](const TypeSpec &y) {
peter klauslerb7cf5122018-03-14 22:31:16990 Word("TYPE IS ("), Walk(y), Put(')');
peter klausler79d044e2018-03-01 00:56:10991 },
992 [&](const DerivedTypeSpec &y) {
peter klauslerb7cf5122018-03-14 22:31:16993 Word("CLASS IS ("), Walk(y), Put(')');
peter klausler79d044e2018-03-01 00:56:10994 },
peter klauslerb7cf5122018-03-14 22:31:16995 [&](const Default &) { Word("CLASS DEFAULT"); }},
peter klausler79d044e2018-03-01 00:56:10996 x.u);
peter klausler79d044e2018-03-01 00:56:10997 }
peter klausler8ea4a0a2018-04-06 20:13:20998 void Unparse(const ExitStmt &x) { // R1156
peter klauslerb7cf5122018-03-14 22:31:16999 Word("EXIT"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:101000 }
peter klausler8ea4a0a2018-04-06 20:13:201001 void Before(const GotoStmt &x) { // R1157
peter klauslerb7cf5122018-03-14 22:31:161002 Word("GO TO ");
peter klausler79d044e2018-03-01 00:56:101003 }
peter klausler8ea4a0a2018-04-06 20:13:201004 void Unparse(const ComputedGotoStmt &x) { // R1158
peter klauslerb7cf5122018-03-14 22:31:161005 Word("GO TO ("), Walk(x.t, "), ");
peter klausler79d044e2018-03-01 00:56:101006 }
peter klausler8ea4a0a2018-04-06 20:13:201007 void Unparse(const ContinueStmt &x) { // R1159
peter klauslerb7cf5122018-03-14 22:31:161008 Word("CONTINUE");
peter klausler79d044e2018-03-01 00:56:101009 }
peter klausler8ea4a0a2018-04-06 20:13:201010 void Unparse(const StopStmt &x) { // R1160, R1161
peter klausler79d044e2018-03-01 00:56:101011 if (std::get<StopStmt::Kind>(x.t) == StopStmt::Kind::ErrorStop) {
peter klauslerb7cf5122018-03-14 22:31:161012 Word("ERROR ");
peter klausler79d044e2018-03-01 00:56:101013 }
peter klauslerb7cf5122018-03-14 22:31:161014 Word("STOP"), Walk(" ", std::get<std::optional<StopCode>>(x.t));
peter klausler79d044e2018-03-01 00:56:101015 Walk(", QUIET=", std::get<std::optional<ScalarLogicalExpr>>(x.t));
peter klausler79d044e2018-03-01 00:56:101016 }
peter klausler8ea4a0a2018-04-06 20:13:201017 void Unparse(const FailImageStmt &x) { // R1163
peter klauslerb7cf5122018-03-14 22:31:161018 Word("FAIL IMAGE");
peter klausler79d044e2018-03-01 00:56:101019 }
peter klausler8ea4a0a2018-04-06 20:13:201020 void Unparse(const SyncAllStmt &x) { // R1164
peter klauslerb7cf5122018-03-14 22:31:161021 Word("SYNC ALL ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101022 }
peter klausler8ea4a0a2018-04-06 20:13:201023 void Unparse(const SyncImagesStmt &x) { // R1166
peter klauslerb7cf5122018-03-14 22:31:161024 Word("SYNC IMAGES (");
1025 Walk(std::get<SyncImagesStmt::ImageSet>(x.t));
peter klausler79d044e2018-03-01 00:56:101026 Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101027 }
peter klausler8ea4a0a2018-04-06 20:13:201028 void Unparse(const SyncMemoryStmt &x) { // R1168
peter klauslerb7cf5122018-03-14 22:31:161029 Word("SYNC MEMORY ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101030 }
peter klausler8ea4a0a2018-04-06 20:13:201031 void Unparse(const SyncTeamStmt &x) { // R1169
peter klauslerb7cf5122018-03-14 22:31:161032 Word("SYNC TEAM ("), Walk(std::get<TeamVariable>(x.t));
peter klausler79d044e2018-03-01 00:56:101033 Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101034 }
peter klausler8ea4a0a2018-04-06 20:13:201035 void Unparse(const EventPostStmt &x) { // R1170
peter klauslerb7cf5122018-03-14 22:31:161036 Word("EVENT POST ("), Walk(std::get<EventVariable>(x.t));
peter klausler79d044e2018-03-01 00:56:101037 Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101038 }
peter klausler8ea4a0a2018-04-06 20:13:201039 void Before(const EventWaitStmt::EventWaitSpec &x) { // R1173, R1174
peter klausler62d9cdd2018-03-15 00:02:211040 std::visit(visitors{[&](const ScalarIntExpr &x) { Word("UNTIL_COUNT="); },
peter klauslered5a6c92018-03-15 00:07:151041 [](const StatOrErrmsg &) {}},
peter klausler79d044e2018-03-01 00:56:101042 x.u);
peter klausler79d044e2018-03-01 00:56:101043 }
peter klausler8ea4a0a2018-04-06 20:13:201044 void Unparse(const EventWaitStmt &x) { // R1170
peter klauslerb7cf5122018-03-14 22:31:161045 Word("EVENT WAIT ("), Walk(std::get<EventVariable>(x.t));
peter klausler79d044e2018-03-01 00:56:101046 Walk(", ", std::get<std::list<EventWaitStmt::EventWaitSpec>>(x.t), ", ");
1047 Put(')');
peter klausler79d044e2018-03-01 00:56:101048 }
peter klausler8ea4a0a2018-04-06 20:13:201049 void Unparse(const FormTeamStmt &x) { // R1175
peter klauslerb7cf5122018-03-14 22:31:161050 Word("FORM TEAM ("), Walk(std::get<ScalarIntExpr>(x.t));
peter klausler79d044e2018-03-01 00:56:101051 Put(','), Walk(std::get<TeamVariable>(x.t));
1052 Walk(", ", std::get<std::list<FormTeamStmt::FormTeamSpec>>(x.t), ", ");
1053 Put(')');
peter klausler79d044e2018-03-01 00:56:101054 }
peter klausler8ea4a0a2018-04-06 20:13:201055 void Before(const FormTeamStmt::FormTeamSpec &x) { // R1176, R1177
peter klausler62d9cdd2018-03-15 00:02:211056 std::visit(visitors{[&](const ScalarIntExpr &x) { Word("NEW_INDEX="); },
peter klauslered5a6c92018-03-15 00:07:151057 [](const StatOrErrmsg &) {}},
peter klausler79d044e2018-03-01 00:56:101058 x.u);
peter klausler79d044e2018-03-01 00:56:101059 }
peter klausler8ea4a0a2018-04-06 20:13:201060 void Unparse(const LockStmt &x) { // R1178
peter klauslerb7cf5122018-03-14 22:31:161061 Word("LOCK ("), Walk(std::get<LockVariable>(x.t));
peter klausler79d044e2018-03-01 00:56:101062 Walk(", ", std::get<std::list<LockStmt::LockStat>>(x.t), ", ");
1063 Put(')');
peter klausler79d044e2018-03-01 00:56:101064 }
peter klausler8ea4a0a2018-04-06 20:13:201065 void Before(const LockStmt::LockStat &x) { // R1179
peter klausler62d9cdd2018-03-15 00:02:211066 std::visit(
1067 visitors{[&](const ScalarLogicalVariable &) { Word("ACQUIRED_LOCK="); },
peter klauslered5a6c92018-03-15 00:07:151068 [](const StatOrErrmsg &y) {}},
peter klausler79d044e2018-03-01 00:56:101069 x.u);
peter klausler79d044e2018-03-01 00:56:101070 }
peter klausler8ea4a0a2018-04-06 20:13:201071 void Unparse(const UnlockStmt &x) { // R1180
peter klauslerb7cf5122018-03-14 22:31:161072 Word("UNLOCK ("), Walk(std::get<LockVariable>(x.t));
peter klausler79d044e2018-03-01 00:56:101073 Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", ");
1074 Put(')');
peter klausler79d044e2018-03-01 00:56:101075 }
1076
peter klausler8ea4a0a2018-04-06 20:13:201077 void Unparse(const OpenStmt &x) { // R1204
peter klauslerb7cf5122018-03-14 22:31:161078 Word("OPEN ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101079 }
1080 bool Pre(const ConnectSpec &x) { // R1205
1081 return std::visit(visitors{[&](const FileUnitNumber &) {
peter klauslerb7cf5122018-03-14 22:31:161082 Word("UNIT=");
peter klausler79d044e2018-03-01 00:56:101083 return true;
1084 },
1085 [&](const FileNameExpr &) {
peter klauslerb7cf5122018-03-14 22:31:161086 Word("FILE=");
peter klausler79d044e2018-03-01 00:56:101087 return true;
1088 },
1089 [&](const ConnectSpec::CharExpr &y) {
1090 Walk(y.t, "=");
1091 return false;
1092 },
1093 [&](const MsgVariable &) {
peter klauslerb7cf5122018-03-14 22:31:161094 Word("IOMSG=");
peter klausler79d044e2018-03-01 00:56:101095 return true;
1096 },
1097 [&](const StatVariable &) {
peter klauslerb7cf5122018-03-14 22:31:161098 Word("IOSTAT=");
peter klausler79d044e2018-03-01 00:56:101099 return true;
1100 },
1101 [&](const ConnectSpec::Recl &) {
peter klauslerb7cf5122018-03-14 22:31:161102 Word("RECL=");
peter klausler79d044e2018-03-01 00:56:101103 return true;
1104 },
1105 [&](const ConnectSpec::Newunit &) {
peter klauslerb7cf5122018-03-14 22:31:161106 Word("NEWUNIT=");
peter klausler79d044e2018-03-01 00:56:101107 return true;
1108 },
1109 [&](const ErrLabel &) {
peter klauslerb7cf5122018-03-14 22:31:161110 Word("ERR=");
peter klausler79d044e2018-03-01 00:56:101111 return true;
1112 },
1113 [&](const StatusExpr &) {
peter klauslerb7cf5122018-03-14 22:31:161114 Word("STATUS=");
peter klausler79d044e2018-03-01 00:56:101115 return true;
1116 }},
1117 x.u);
1118 }
peter klausler8ea4a0a2018-04-06 20:13:201119 void Unparse(const CloseStmt &x) { // R1208
peter klauslerb7cf5122018-03-14 22:31:161120 Word("CLOSE ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101121 }
peter klausler8ea4a0a2018-04-06 20:13:201122 void Before(const CloseStmt::CloseSpec &x) { // R1209
peter klauslerb7cf5122018-03-14 22:31:161123 std::visit(visitors{[&](const FileUnitNumber &) { Word("UNIT="); },
1124 [&](const StatVariable &) { Word("IOSTAT="); },
1125 [&](const MsgVariable &) { Word("IOMSG="); },
1126 [&](const ErrLabel &) { Word("ERR="); },
1127 [&](const StatusExpr &) { Word("STATUS="); }},
peter klausler79d044e2018-03-01 00:56:101128 x.u);
peter klausler79d044e2018-03-01 00:56:101129 }
peter klausler8ea4a0a2018-04-06 20:13:201130 void Unparse(const ReadStmt &x) { // R1210
peter klauslerb7cf5122018-03-14 22:31:161131 Word("READ ");
peter klausler79d044e2018-03-01 00:56:101132 if (x.iounit) {
1133 Put('('), Walk(x.iounit);
1134 if (x.format) {
1135 Put(", "), Walk(x.format);
1136 }
peter klauslerdcd09422018-03-15 23:03:281137 Walk(", ", x.controls, ", ");
peter klausler79d044e2018-03-01 00:56:101138 Put(')');
1139 } else if (x.format) {
1140 Walk(x.format);
1141 if (!x.items.empty()) {
1142 Put(", ");
1143 }
1144 } else {
peter klauslerdcd09422018-03-15 23:03:281145 Put('('), Walk(x.controls, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101146 }
1147 Walk(" ", x.items, ", ");
peter klausler79d044e2018-03-01 00:56:101148 }
peter klausler8ea4a0a2018-04-06 20:13:201149 void Unparse(const WriteStmt &x) { // R1211
peter klauslerb7cf5122018-03-14 22:31:161150 Word("WRITE (");
peter klausler79d044e2018-03-01 00:56:101151 if (x.iounit) {
1152 Walk(x.iounit);
1153 if (x.format) {
1154 Put(", "), Walk(x.format);
1155 }
peter klauslerdcd09422018-03-15 23:03:281156 Walk(", ", x.controls, ", ");
peter klausler79d044e2018-03-01 00:56:101157 } else {
peter klauslerdcd09422018-03-15 23:03:281158 Walk(x.controls, ", ");
peter klausler79d044e2018-03-01 00:56:101159 }
1160 Put(')'), Walk(" ", x.items, ", ");
peter klausler79d044e2018-03-01 00:56:101161 }
peter klausler8ea4a0a2018-04-06 20:13:201162 void Unparse(const PrintStmt &x) { // R1212
peter klauslerb7cf5122018-03-14 22:31:161163 Word("PRINT "), Walk(std::get<Format>(x.t));
peter klausler79d044e2018-03-01 00:56:101164 Walk(", ", std::get<std::list<OutputItem>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:101165 }
1166 bool Pre(const IoControlSpec &x) { // R1213
1167 return std::visit(visitors{[&](const IoUnit &) {
peter klauslerb7cf5122018-03-14 22:31:161168 Word("UNIT=");
peter klausler79d044e2018-03-01 00:56:101169 return true;
1170 },
1171 [&](const Format &) {
peter klauslerb7cf5122018-03-14 22:31:161172 Word("FMT=");
peter klausler79d044e2018-03-01 00:56:101173 return true;
1174 },
1175 [&](const Name &) {
peter klauslerb7cf5122018-03-14 22:31:161176 Word("NML=");
peter klausler79d044e2018-03-01 00:56:101177 return true;
1178 },
1179 [&](const IoControlSpec::CharExpr &y) {
1180 Walk(y.t, "=");
1181 return false;
1182 },
1183 [&](const IoControlSpec::Asynchronous &) {
peter klauslerb7cf5122018-03-14 22:31:161184 Word("ASYNCHRONOUS=");
peter klausler79d044e2018-03-01 00:56:101185 return true;
1186 },
1187 [&](const EndLabel &) {
peter klauslerb7cf5122018-03-14 22:31:161188 Word("END=");
peter klausler79d044e2018-03-01 00:56:101189 return true;
1190 },
1191 [&](const EorLabel &) {
peter klauslerb7cf5122018-03-14 22:31:161192 Word("EOR=");
peter klausler79d044e2018-03-01 00:56:101193 return true;
1194 },
1195 [&](const ErrLabel &) {
peter klauslerb7cf5122018-03-14 22:31:161196 Word("ERR=");
peter klausler79d044e2018-03-01 00:56:101197 return true;
1198 },
1199 [&](const IdVariable &) {
peter klauslerb7cf5122018-03-14 22:31:161200 Word("ID=");
peter klausler79d044e2018-03-01 00:56:101201 return true;
1202 },
1203 [&](const MsgVariable &) {
peter klauslerb7cf5122018-03-14 22:31:161204 Word("IOMSG=");
peter klausler79d044e2018-03-01 00:56:101205 return true;
1206 },
1207 [&](const StatVariable &) {
peter klauslerb7cf5122018-03-14 22:31:161208 Word("IOSTAT=");
peter klausler79d044e2018-03-01 00:56:101209 return true;
1210 },
1211 [&](const IoControlSpec::Pos &) {
peter klauslerb7cf5122018-03-14 22:31:161212 Word("POS=");
peter klausler79d044e2018-03-01 00:56:101213 return true;
1214 },
1215 [&](const IoControlSpec::Rec &) {
peter klauslerb7cf5122018-03-14 22:31:161216 Word("REC=");
peter klausler79d044e2018-03-01 00:56:101217 return true;
1218 },
1219 [&](const IoControlSpec::Size &) {
peter klauslerb7cf5122018-03-14 22:31:161220 Word("SIZE=");
peter klausler79d044e2018-03-01 00:56:101221 return true;
1222 }},
1223 x.u);
1224 }
peter klausler8ea4a0a2018-04-06 20:13:201225 void Unparse(const InputImpliedDo &x) { // R1218
peter klausler79d044e2018-03-01 00:56:101226 Put('('), Walk(std::get<std::list<InputItem>>(x.t), ", "), Put(", ");
1227 Walk(std::get<IoImpliedDoControl>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:101228 }
peter klausler8ea4a0a2018-04-06 20:13:201229 void Unparse(const OutputImpliedDo &x) { // R1219
peter klausler79d044e2018-03-01 00:56:101230 Put('('), Walk(std::get<std::list<OutputItem>>(x.t), ", "), Put(", ");
1231 Walk(std::get<IoImpliedDoControl>(x.t)), Put(')');
peter klausler79d044e2018-03-01 00:56:101232 }
peter klausler8ea4a0a2018-04-06 20:13:201233 void Unparse(const WaitStmt &x) { // R1222
peter klauslerb7cf5122018-03-14 22:31:161234 Word("WAIT ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101235 }
peter klausler8ea4a0a2018-04-06 20:13:201236 void Before(const WaitSpec &x) { // R1223
peter klauslerb7cf5122018-03-14 22:31:161237 std::visit(visitors{[&](const FileUnitNumber &) { Word("UNIT="); },
1238 [&](const EndLabel &) { Word("END="); },
1239 [&](const EorLabel &) { Word("EOR="); },
1240 [&](const ErrLabel &) { Word("ERR="); },
1241 [&](const IdExpr &) { Word("ID="); },
1242 [&](const MsgVariable &) { Word("IOMSG="); },
1243 [&](const StatVariable &) { Word("IOSTAT="); }},
peter klausler79d044e2018-03-01 00:56:101244 x.u);
peter klausler79d044e2018-03-01 00:56:101245 }
peter klausler8ea4a0a2018-04-06 20:13:201246 void Unparse(const BackspaceStmt &x) { // R1224
peter klauslerb7cf5122018-03-14 22:31:161247 Word("BACKSPACE ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101248 }
peter klausler8ea4a0a2018-04-06 20:13:201249 void Unparse(const EndfileStmt &x) { // R1225
peter klauslerb7cf5122018-03-14 22:31:161250 Word("ENDFILE ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101251 }
peter klausler8ea4a0a2018-04-06 20:13:201252 void Unparse(const RewindStmt &x) { // R1226
peter klauslerb7cf5122018-03-14 22:31:161253 Word("REWIND ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101254 }
peter klausler8ea4a0a2018-04-06 20:13:201255 void Before(const PositionOrFlushSpec &x) { // R1227 & R1229
peter klauslerad4adc22018-03-16 00:09:271256 std::visit(visitors{[&](const FileUnitNumber &) { Word("UNIT="); },
1257 [&](const MsgVariable &) { Word("IOMSG="); },
1258 [&](const StatVariable &) { Word("IOSTAT="); },
1259 [&](const ErrLabel &) { Word("ERR="); }},
1260 x.u);
peter klauslerad4adc22018-03-16 00:09:271261 }
peter klausler8ea4a0a2018-04-06 20:13:201262 void Unparse(const FlushStmt &x) { // R1228
peter klauslerb7cf5122018-03-14 22:31:161263 Word("FLUSH ("), Walk(x.v, ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101264 }
peter klausler8ea4a0a2018-04-06 20:13:201265 void Unparse(const InquireStmt &x) { // R1230
peter klauslerb7cf5122018-03-14 22:31:161266 Word("INQUIRE (");
peter klausler79d044e2018-03-01 00:56:101267 std::visit(
1268 visitors{[&](const InquireStmt::Iolength &y) {
peter klauslerb7cf5122018-03-14 22:31:161269 Word("IOLENGTH="), Walk(y.t, ") ");
peter klausler79d044e2018-03-01 00:56:101270 },
1271 [&](const std::list<InquireSpec> &y) { Walk(y, ", "), Put(')'); }},
1272 x.u);
peter klausler79d044e2018-03-01 00:56:101273 }
1274 bool Pre(const InquireSpec &x) { // R1231
1275 return std::visit(visitors{[&](const FileUnitNumber &) {
peter klauslerb7cf5122018-03-14 22:31:161276 Word("UNIT=");
peter klausler79d044e2018-03-01 00:56:101277 return true;
1278 },
1279 [&](const FileNameExpr &) {
peter klauslerb7cf5122018-03-14 22:31:161280 Word("FILE=");
peter klausler79d044e2018-03-01 00:56:101281 return true;
1282 },
1283 [&](const InquireSpec::CharVar &y) {
1284 Walk(y.t, "=");
1285 return false;
1286 },
1287 [&](const InquireSpec::IntVar &y) {
1288 Walk(y.t, "=");
1289 return false;
1290 },
1291 [&](const InquireSpec::LogVar &y) {
1292 Walk(y.t, "=");
1293 return false;
1294 },
1295 [&](const IdExpr &) {
peter klauslerb7cf5122018-03-14 22:31:161296 Word("ID=");
peter klausler79d044e2018-03-01 00:56:101297 return true;
1298 },
1299 [&](const ErrLabel &) {
peter klauslerb7cf5122018-03-14 22:31:161300 Word("ERR=");
peter klausler79d044e2018-03-01 00:56:101301 return true;
1302 }},
1303 x.u);
1304 }
1305
peter klausler8ea4a0a2018-04-06 20:13:201306 void Before(const FormatStmt &) { // R1301
peter klauslerb7cf5122018-03-14 22:31:161307 Word("FORMAT");
peter klausler79d044e2018-03-01 00:56:101308 }
peter klausler8ea4a0a2018-04-06 20:13:201309 void Unparse(const format::FormatSpecification &x) { // R1302, R1303, R1305
peter klausler79d044e2018-03-01 00:56:101310 Put('('), Walk("", x.items, ",", x.unlimitedItems.empty() ? "" : ",");
1311 Walk("*(", x.unlimitedItems, ",", ")"), Put(')');
peter klausler79d044e2018-03-01 00:56:101312 }
peter klausler8ea4a0a2018-04-06 20:13:201313 void Unparse(const format::FormatItem &x) { // R1304, R1306, R1321
peter klausler79d044e2018-03-01 00:56:101314 if (x.repeatCount.has_value()) {
1315 Walk(*x.repeatCount);
1316 }
1317 std::visit(visitors{[&](const std::string &y) { PutQuoted(y); },
1318 [&](const std::list<format::FormatItem> &y) {
1319 Walk("(", y, ",", ")");
1320 },
1321 [&](const auto &y) { Walk(y); }},
1322 x.u);
peter klausler79d044e2018-03-01 00:56:101323 }
peter klausler8ea4a0a2018-04-06 20:13:201324 void Unparse(
1325 const format::IntrinsicTypeDataEditDesc &x) { // R1307(1/2) - R1311
peter klausler79d044e2018-03-01 00:56:101326 switch (x.kind) {
1327#define FMT(x) \
1328 case format::IntrinsicTypeDataEditDesc::Kind::x: Put(#x); break
1329 FMT(I);
1330 FMT(B);
1331 FMT(O);
1332 FMT(Z);
1333 FMT(F);
1334 FMT(E);
1335 FMT(EN);
1336 FMT(ES);
1337 FMT(EX);
1338 FMT(G);
1339 FMT(L);
1340 FMT(A);
1341 FMT(D);
1342#undef FMT
1343 default: CRASH_NO_CASE;
1344 }
1345 Walk(x.width), Walk(".", x.digits), Walk("E", x.exponentWidth);
peter klausler79d044e2018-03-01 00:56:101346 }
peter klausler8ea4a0a2018-04-06 20:13:201347 void Unparse(const format::DerivedTypeDataEditDesc &x) { // R1307(2/2), R1312
peter klauslerb7cf5122018-03-14 22:31:161348 Word("DT");
peter klausler79d044e2018-03-01 00:56:101349 if (!x.type.empty()) {
1350 Put('"'), Put(x.type), Put('"');
1351 }
1352 Walk("(", x.parameters, ",", ")");
peter klausler79d044e2018-03-01 00:56:101353 }
peter klausler8ea4a0a2018-04-06 20:13:201354 void Unparse(const format::ControlEditDesc &x) { // R1313, R1315-R1320
peter klausler79d044e2018-03-01 00:56:101355 switch (x.kind) {
1356 case format::ControlEditDesc::Kind::T:
peter klauslerb7cf5122018-03-14 22:31:161357 Word("T");
peter klausler79d044e2018-03-01 00:56:101358 Walk(x.count);
1359 break;
1360 case format::ControlEditDesc::Kind::TL:
peter klauslerb7cf5122018-03-14 22:31:161361 Word("TL");
peter klausler79d044e2018-03-01 00:56:101362 Walk(x.count);
1363 break;
1364 case format::ControlEditDesc::Kind::TR:
peter klauslerb7cf5122018-03-14 22:31:161365 Word("TR");
peter klausler79d044e2018-03-01 00:56:101366 Walk(x.count);
1367 break;
1368 case format::ControlEditDesc::Kind::X:
1369 if (x.count != 1) {
1370 Walk(x.count);
1371 }
peter klauslerb7cf5122018-03-14 22:31:161372 Word("X");
peter klausler79d044e2018-03-01 00:56:101373 break;
1374 case format::ControlEditDesc::Kind::Slash:
1375 if (x.count != 1) {
1376 Walk(x.count);
1377 }
1378 Put('/');
1379 break;
1380 case format::ControlEditDesc::Kind::Colon: Put(':'); break;
1381 case format::ControlEditDesc::Kind::P:
1382 Walk(x.count);
peter klauslerb7cf5122018-03-14 22:31:161383 Word("P");
peter klausler79d044e2018-03-01 00:56:101384 break;
1385#define FMT(x) \
1386 case format::ControlEditDesc::Kind::x: Put(#x); break
1387 FMT(SS);
1388 FMT(SP);
1389 FMT(S);
1390 FMT(BN);
1391 FMT(BZ);
1392 FMT(RU);
1393 FMT(RD);
1394 FMT(RZ);
1395 FMT(RN);
1396 FMT(RC);
1397 FMT(RP);
1398 FMT(DC);
1399 FMT(DP);
1400#undef FMT
1401 default: CRASH_NO_CASE;
1402 }
peter klausler79d044e2018-03-01 00:56:101403 }
1404
peter klausler8ea4a0a2018-04-06 20:13:201405 void Before(const MainProgram &x) { // R1401
peter klausler79d044e2018-03-01 00:56:101406 if (!std::get<std::optional<Statement<ProgramStmt>>>(x.t)) {
1407 Indent();
1408 }
peter klausler79d044e2018-03-01 00:56:101409 }
peter klausler8ea4a0a2018-04-06 20:13:201410 void Before(const ProgramStmt &x) { // R1402
peter klauslerb7cf5122018-03-14 22:31:161411 Word("PROGRAM "), Indent();
peter klausler79d044e2018-03-01 00:56:101412 }
peter klausler8ea4a0a2018-04-06 20:13:201413 void Unparse(const EndProgramStmt &x) { // R1403
peter klausler41d9cfd2018-04-03 17:29:041414 EndSubprogram("PROGRAM", x.v);
peter klausler79d044e2018-03-01 00:56:101415 }
peter klausler8ea4a0a2018-04-06 20:13:201416 void Before(const ModuleStmt &) { // R1405
peter klauslerb7cf5122018-03-14 22:31:161417 Word("MODULE "), Indent();
peter klausler79d044e2018-03-01 00:56:101418 }
peter klausler8ea4a0a2018-04-06 20:13:201419 void Unparse(const EndModuleStmt &x) { // R1406
peter klausler41d9cfd2018-04-03 17:29:041420 EndSubprogram("MODULE", x.v);
peter klausler79d044e2018-03-01 00:56:101421 }
peter klausler8ea4a0a2018-04-06 20:13:201422 void Unparse(const UseStmt &x) { // R1409
peter klauslerb7cf5122018-03-14 22:31:161423 Word("USE"), Walk(", ", x.nature), Put(" :: "), Walk(x.moduleName);
peter klausler79d044e2018-03-01 00:56:101424 std::visit(
1425 visitors{[&](const std::list<Rename> &y) { Walk(", ", y, ", "); },
1426 [&](const std::list<Only> &y) { Walk(", ONLY: ", y, ", "); }},
1427 x.u);
peter klausler79d044e2018-03-01 00:56:101428 }
peter klausler8ea4a0a2018-04-06 20:13:201429 void Unparse(const Rename &x) { // R1411
peter klausler79d044e2018-03-01 00:56:101430 std::visit(visitors{[&](const Rename::Names &y) { Walk(y.t, " => "); },
1431 [&](const Rename::Operators &y) {
peter klausler8e7c0082018-04-09 21:52:151432 Word("OPERATOR("), Walk(y.t, ") => OPERATOR("), Put(")");
peter klausler79d044e2018-03-01 00:56:101433 }},
1434 x.u);
peter klausler79d044e2018-03-01 00:56:101435 }
peter klausler8ea4a0a2018-04-06 20:13:201436 void Before(const SubmoduleStmt &x) { // R1417
peter klauslerb7cf5122018-03-14 22:31:161437 Word("SUBMODULE "), Indent();
peter klausler79d044e2018-03-01 00:56:101438 }
peter klausler8ea4a0a2018-04-06 20:13:201439 void Unparse(const ParentIdentifier &x) { // R1418
peter klausler79d044e2018-03-01 00:56:101440 Walk(std::get<Name>(x.t)), Walk(":", std::get<std::optional<Name>>(x.t));
peter klausler79d044e2018-03-01 00:56:101441 }
peter klausler8ea4a0a2018-04-06 20:13:201442 void Unparse(const EndSubmoduleStmt &x) { // R1419
peter klausler41d9cfd2018-04-03 17:29:041443 EndSubprogram("SUBMODULE", x.v);
peter klausler79d044e2018-03-01 00:56:101444 }
peter klausler8ea4a0a2018-04-06 20:13:201445 void Unparse(const BlockDataStmt &x) { // R1421
peter klauslerb7cf5122018-03-14 22:31:161446 Word("BLOCK DATA"), Walk(" ", x.v), Indent();
peter klausler79d044e2018-03-01 00:56:101447 }
peter klausler8ea4a0a2018-04-06 20:13:201448 void Unparse(const EndBlockDataStmt &x) { // R1422
peter klausler41d9cfd2018-04-03 17:29:041449 EndSubprogram("BLOCK DATA", x.v);
peter klausler79d044e2018-03-01 00:56:101450 }
1451
peter klausler8ea4a0a2018-04-06 20:13:201452 void Unparse(const InterfaceStmt &x) { // R1503
peter klausler79d044e2018-03-01 00:56:101453 std::visit(visitors{[&](const std::optional<GenericSpec> &y) {
peter klauslerb7cf5122018-03-14 22:31:161454 Word("INTERFACE"), Walk(" ", y);
peter klausler79d044e2018-03-01 00:56:101455 },
peter klauslerb7cf5122018-03-14 22:31:161456 [&](const Abstract &) { Word("ABSTRACT INTERFACE"); }},
peter klausler79d044e2018-03-01 00:56:101457 x.u);
1458 Indent();
peter klausler79d044e2018-03-01 00:56:101459 }
peter klausler8ea4a0a2018-04-06 20:13:201460 void Unparse(const EndInterfaceStmt &x) { // R1504
peter klauslerb7cf5122018-03-14 22:31:161461 Outdent(), Word("END INTERFACE"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:101462 }
peter klausler8ea4a0a2018-04-06 20:13:201463 void Unparse(const ProcedureStmt &x) { // R1506
peter klausler79d044e2018-03-01 00:56:101464 if (std::get<ProcedureStmt::Kind>(x.t) ==
1465 ProcedureStmt::Kind::ModuleProcedure) {
peter klauslerb7cf5122018-03-14 22:31:161466 Word("MODULE ");
peter klausler79d044e2018-03-01 00:56:101467 }
peter klauslerb7cf5122018-03-14 22:31:161468 Word("PROCEDURE :: ");
peter klausler79d044e2018-03-01 00:56:101469 Walk(std::get<std::list<Name>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:101470 }
peter klausler8ea4a0a2018-04-06 20:13:201471 void Before(const GenericSpec &x) { // R1508, R1509
peter klauslerd71f3cf2018-03-14 23:31:411472 std::visit(
1473 visitors{[&](const DefinedOperator &x) { Word("OPERATOR("); },
1474 [&](const GenericSpec::Assignment &) { Word("ASSIGNMENT(=)"); },
1475 [&](const GenericSpec::ReadFormatted &) {
1476 Word("READ(FORMATTED)");
1477 },
1478 [&](const GenericSpec::ReadUnformatted &) {
1479 Word("READ(UNFORMATTED)");
1480 },
1481 [&](const GenericSpec::WriteFormatted &) {
1482 Word("WRITE(FORMATTED)");
1483 },
1484 [&](const GenericSpec::WriteUnformatted &) {
1485 Word("WRITE(UNFORMATTED)");
1486 },
1487 [](const auto &) {}},
peter klausler79d044e2018-03-01 00:56:101488 x.u);
peter klausler79d044e2018-03-01 00:56:101489 }
peter klauslerd71f3cf2018-03-14 23:31:411490 void Post(const GenericSpec &x) {
1491 std::visit(visitors{[&](const DefinedOperator &x) { Put(')'); },
1492 [](const auto &) {}},
1493 x.u);
1494 }
peter klausler8ea4a0a2018-04-06 20:13:201495 void Unparse(const GenericStmt &x) { // R1510
peter klauslerb7cf5122018-03-14 22:31:161496 Word("GENERIC"), Walk(", ", std::get<std::optional<AccessSpec>>(x.t));
peter klausler79d044e2018-03-01 00:56:101497 Put(" :: "), Walk(std::get<GenericSpec>(x.t)), Put(" => ");
1498 Walk(std::get<std::list<Name>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:101499 }
peter klausler8ea4a0a2018-04-06 20:13:201500 void Unparse(const ExternalStmt &x) { // R1511
peter klauslerb7cf5122018-03-14 22:31:161501 Word("EXTERNAL :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:101502 }
peter klausler8ea4a0a2018-04-06 20:13:201503 void Unparse(const ProcedureDeclarationStmt &x) { // R1512
peter klauslerb7cf5122018-03-14 22:31:161504 Word("PROCEDURE ("), Walk(std::get<std::optional<ProcInterface>>(x.t));
peter klausler79d044e2018-03-01 00:56:101505 Put(')'), Walk(", ", std::get<std::list<ProcAttrSpec>>(x.t), ", ");
1506 Put(" :: "), Walk(std::get<std::list<ProcDecl>>(x.t), ", ");
peter klausler79d044e2018-03-01 00:56:101507 }
peter klausler8ea4a0a2018-04-06 20:13:201508 void Unparse(const ProcDecl &x) { // R1515
peter klausler79d044e2018-03-01 00:56:101509 Walk(std::get<Name>(x.t));
1510 Walk(" => ", std::get<std::optional<ProcPointerInit>>(x.t));
peter klausler79d044e2018-03-01 00:56:101511 }
peter klausler8ea4a0a2018-04-06 20:13:201512 void Unparse(const IntrinsicStmt &x) { // R1519
peter klauslerb7cf5122018-03-14 22:31:161513 Word("INTRINSIC :: "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:101514 }
peter klausler8ea4a0a2018-04-06 20:13:201515 void Unparse(const FunctionReference &x) { // R1520
peter klausler79d044e2018-03-01 00:56:101516 Walk(std::get<ProcedureDesignator>(x.v.t));
1517 Put('('), Walk(std::get<std::list<ActualArgSpec>>(x.v.t), ", "), Put(')');
peter klausler79d044e2018-03-01 00:56:101518 }
peter klausler8ea4a0a2018-04-06 20:13:201519 void Unparse(const CallStmt &x) { // R1521
peter klauslerad4adc22018-03-16 00:09:271520 const auto &pd = std::get<ProcedureDesignator>(x.v.t);
1521 const auto &args = std::get<std::list<ActualArgSpec>>(x.v.t);
1522 Word("CALL "), Walk(pd);
1523 if (args.empty()) {
1524 if (std::holds_alternative<ProcComponentRef>(pd.u)) {
1525 Put("()"); // pgf90 crashes on CALL to tbp without parentheses
1526 }
1527 } else {
1528 Walk("(", args, ", ", ")");
1529 }
peter klausler79d044e2018-03-01 00:56:101530 }
peter klausler8ea4a0a2018-04-06 20:13:201531 void Unparse(const ActualArgSpec &x) { // R1523
peter klausler79d044e2018-03-01 00:56:101532 Walk(std::get<std::optional<Keyword>>(x.t), "=");
1533 Walk(std::get<ActualArg>(x.t));
peter klausler79d044e2018-03-01 00:56:101534 }
peter klausler8ea4a0a2018-04-06 20:13:201535 void Unparse(const ActualArg::PercentRef &x) { // R1524
peter klauslerb7cf5122018-03-14 22:31:161536 Word("%REF("), Walk(x.v), Put(')');
peter klausler79d044e2018-03-01 00:56:101537 }
peter klausler8ea4a0a2018-04-06 20:13:201538 void Unparse(const ActualArg::PercentVal &x) {
peter klauslerb7cf5122018-03-14 22:31:161539 Word("%VAL("), Walk(x.v), Put(')');
peter klausler79d044e2018-03-01 00:56:101540 }
peter klausler8ea4a0a2018-04-06 20:13:201541 void Before(const AltReturnSpec &) { // R1525
peter klauslerb7cf5122018-03-14 22:31:161542 Put('*');
peter klausler79d044e2018-03-01 00:56:101543 }
peter klauslerd71f3cf2018-03-14 23:31:411544 void Post(const PrefixSpec::Elemental) { Word("ELEMENTAL"); } // R1527
1545 void Post(const PrefixSpec::Impure) { Word("IMPURE"); }
1546 void Post(const PrefixSpec::Module) { Word("MODULE"); }
1547 void Post(const PrefixSpec::Non_Recursive) { Word("NON_RECURSIVE"); }
1548 void Post(const PrefixSpec::Pure) { Word("PURE"); }
1549 void Post(const PrefixSpec::Recursive) { Word("RECURSIVE"); }
peter klausler8ea4a0a2018-04-06 20:13:201550 void Unparse(const FunctionStmt &x) { // R1530
peter klausler79d044e2018-03-01 00:56:101551 Walk("", std::get<std::list<PrefixSpec>>(x.t), " ", " ");
peter klausler62d9cdd2018-03-15 00:02:211552 Word("FUNCTION "), Walk(std::get<Name>(x.t)), Put("(");
peter klausler79d044e2018-03-01 00:56:101553 Walk(std::get<std::list<Name>>(x.t), ", "), Put(')');
1554 Walk(" ", std::get<std::optional<Suffix>>(x.t)), Indent();
peter klausler79d044e2018-03-01 00:56:101555 }
peter klausler8ea4a0a2018-04-06 20:13:201556 void Unparse(const Suffix &x) { // R1532
peter klausler79d044e2018-03-01 00:56:101557 if (x.resultName) {
peter klauslerb7cf5122018-03-14 22:31:161558 Word("RESULT("), Walk(x.resultName), Put(')');
peter klausler79d044e2018-03-01 00:56:101559 Walk(" ", x.binding);
1560 } else {
1561 Walk(x.binding);
1562 }
peter klausler79d044e2018-03-01 00:56:101563 }
peter klausler8ea4a0a2018-04-06 20:13:201564 void Unparse(const EndFunctionStmt &x) { // R1533
peter klausler41d9cfd2018-04-03 17:29:041565 EndSubprogram("FUNCTION", x.v);
peter klausler79d044e2018-03-01 00:56:101566 }
peter klausler8ea4a0a2018-04-06 20:13:201567 void Unparse(const SubroutineStmt &x) { // R1535
peter klausler79d044e2018-03-01 00:56:101568 Walk("", std::get<std::list<PrefixSpec>>(x.t), " ", " ");
peter klauslerb7cf5122018-03-14 22:31:161569 Word("SUBROUTINE "), Walk(std::get<Name>(x.t));
peter klauslerd71f3cf2018-03-14 23:31:411570 const auto &args = std::get<std::list<DummyArg>>(x.t);
1571 const auto &bind = std::get<std::optional<LanguageBindingSpec>>(x.t);
1572 if (args.empty()) {
1573 Walk(" () ", bind);
1574 } else {
1575 Walk(" (", args, ", ", ")");
1576 Walk(" ", bind);
1577 }
peter klausler79d044e2018-03-01 00:56:101578 Indent();
peter klausler79d044e2018-03-01 00:56:101579 }
peter klausler8ea4a0a2018-04-06 20:13:201580 void Unparse(const EndSubroutineStmt &x) { // R1537
peter klausler41d9cfd2018-04-03 17:29:041581 EndSubprogram("SUBROUTINE", x.v);
peter klausler79d044e2018-03-01 00:56:101582 }
peter klausler8ea4a0a2018-04-06 20:13:201583 void Before(const MpSubprogramStmt &) { // R1539
peter klauslerb7cf5122018-03-14 22:31:161584 Word("MODULE PROCEDURE "), Indent();
peter klausler79d044e2018-03-01 00:56:101585 }
peter klausler8ea4a0a2018-04-06 20:13:201586 void Unparse(const EndMpSubprogramStmt &x) { // R1540
peter klausler41d9cfd2018-04-03 17:29:041587 EndSubprogram("PROCEDURE", x.v);
peter klausler79d044e2018-03-01 00:56:101588 }
peter klausler8ea4a0a2018-04-06 20:13:201589 void Unparse(const EntryStmt &x) { // R1541
peter klauslerbdd93dd2018-04-09 20:45:301590 Word("ENTRY "), Walk(std::get<Name>(x.t)), Put("(");
1591 Walk(std::get<std::list<DummyArg>>(x.t), ", "), Put(")");
peter klausler79d044e2018-03-01 00:56:101592 Walk(" ", std::get<std::optional<Suffix>>(x.t));
peter klausler79d044e2018-03-01 00:56:101593 }
peter klausler8ea4a0a2018-04-06 20:13:201594 void Unparse(const ReturnStmt &x) { // R1542
peter klauslerb7cf5122018-03-14 22:31:161595 Word("RETURN"), Walk(" ", x.v);
peter klausler79d044e2018-03-01 00:56:101596 }
peter klausler8ea4a0a2018-04-06 20:13:201597 void Unparse(const ContainsStmt &x) { // R1543
peter klausler79d044e2018-03-01 00:56:101598 Outdent();
peter klauslerb7cf5122018-03-14 22:31:161599 Word("CONTAINS");
peter klausler79d044e2018-03-01 00:56:101600 Indent();
peter klausler79d044e2018-03-01 00:56:101601 }
peter klausler8ea4a0a2018-04-06 20:13:201602 void Unparse(const StmtFunctionStmt &x) { // R1544
peter klausler79d044e2018-03-01 00:56:101603 Walk(std::get<Name>(x.t)), Put('(');
1604 Walk(std::get<std::list<Name>>(x.t), ", "), Put(") = ");
1605 Walk(std::get<Scalar<Expr>>(x.t));
peter klausler79d044e2018-03-01 00:56:101606 }
1607
peter klausler75b29332018-03-23 22:14:521608 // Directives, extensions, and deprecated constructs
peter klausler8ea4a0a2018-04-06 20:13:201609 void Unparse(const CompilerDirective &x) {
peter klausler75b29332018-03-23 22:14:521610 std::visit(
1611 visitors{[&](const std::list<CompilerDirective::IgnoreTKR> &tkr) {
1612 Word("!DIR$ IGNORE_TKR");
1613 Walk(" ", tkr, ", ");
1614 },
1615 [&](const CompilerDirective::IVDEP &) { Word("!DIR$ IVDEP\n"); }},
1616 x.u);
1617 Put('\n');
peter klausler75b29332018-03-23 22:14:521618 }
peter klausler8ea4a0a2018-04-06 20:13:201619 void Unparse(const CompilerDirective::IgnoreTKR &x) {
peter klausler75b29332018-03-23 22:14:521620 const auto &list = std::get<std::list<const char *>>(x.t);
1621 if (!list.empty()) {
1622 Put("(");
1623 for (const char *tkr : list) {
1624 Put(*tkr);
1625 }
1626 Put(") ");
1627 }
1628 Walk(std::get<Name>(x.t));
peter klausler75b29332018-03-23 22:14:521629 }
peter klausler8ea4a0a2018-04-06 20:13:201630 void Unparse(const BasedPointerStmt &x) {
peter klauslerb7cf5122018-03-14 22:31:161631 Word("POINTER ("), Walk(std::get<0>(x.t)), Put(", ");
1632 Walk(std::get<1>(x.t));
peter klausler79d044e2018-03-01 00:56:101633 Walk("(", std::get<std::optional<ArraySpec>>(x.t), ")"), Put(')');
peter klausler79d044e2018-03-01 00:56:101634 }
peter klausler4e354d82018-03-30 22:23:371635 void Post(const StructureField &x) {
1636 if (const auto *def = std::get_if<Statement<DataComponentDefStmt>>(&x.u)) {
1637 for (const auto &decl :
1638 std::get<std::list<ComponentDecl>>(def->statement.t)) {
1639 structureComponents_.insert(std::get<Name>(decl.t).source);
1640 }
1641 }
1642 }
peter klausler8ea4a0a2018-04-06 20:13:201643 void Unparse(const StructureStmt &x) {
peter klauslerb7cf5122018-03-14 22:31:161644 Word("STRUCTURE ");
peter klausler79d044e2018-03-01 00:56:101645 if (std::get<bool>(x.t)) { // slashes around name
1646 Put('/'), Walk(std::get<Name>(x.t)), Put('/');
1647 Walk(" ", std::get<std::list<EntityDecl>>(x.t), ", ");
1648 } else {
1649 CHECK(std::get<std::list<EntityDecl>>(x.t).empty());
1650 Walk(std::get<Name>(x.t));
1651 }
1652 Indent();
peter klausler79d044e2018-03-01 00:56:101653 }
peter klauslerb7cf5122018-03-14 22:31:161654 void Post(const Union::UnionStmt &) { Word("UNION"), Indent(); }
1655 void Post(const Union::EndUnionStmt &) { Outdent(), Word("END UNION"); }
1656 void Post(const Map::MapStmt &) { Word("MAP"), Indent(); }
1657 void Post(const Map::EndMapStmt &) { Outdent(), Word("END MAP"); }
peter klausler79d044e2018-03-01 00:56:101658 void Post(const StructureDef::EndStructureStmt &) {
peter klauslerb7cf5122018-03-14 22:31:161659 Outdent(), Word("END STRUCTURE");
peter klausler79d044e2018-03-01 00:56:101660 }
peter klausler8ea4a0a2018-04-06 20:13:201661 void Unparse(const OldParameterStmt &x) {
peter klauslerb7cf5122018-03-14 22:31:161662 Word("PARAMETER "), Walk(x.v, ", ");
peter klausler79d044e2018-03-01 00:56:101663 }
peter klausler8ea4a0a2018-04-06 20:13:201664 void Unparse(const ArithmeticIfStmt &x) {
peter klauslerb7cf5122018-03-14 22:31:161665 Word("IF ("), Walk(std::get<Expr>(x.t)), Put(") ");
peter klausler79d044e2018-03-01 00:56:101666 Walk(std::get<1>(x.t)), Put(", ");
1667 Walk(std::get<2>(x.t)), Put(", ");
1668 Walk(std::get<3>(x.t));
peter klausler79d044e2018-03-01 00:56:101669 }
peter klausler8ea4a0a2018-04-06 20:13:201670 void Unparse(const AssignStmt &x) {
peter klauslerb7cf5122018-03-14 22:31:161671 Word("ASSIGN "), Walk(std::get<Label>(x.t));
1672 Word(" TO "), Walk(std::get<Name>(x.t));
peter klausler79d044e2018-03-01 00:56:101673 }
peter klausler8ea4a0a2018-04-06 20:13:201674 void Unparse(const AssignedGotoStmt &x) {
peter klauslerb7cf5122018-03-14 22:31:161675 Word("GO TO "), Walk(std::get<Name>(x.t));
peter klausler79d044e2018-03-01 00:56:101676 Walk(", (", std::get<std::list<Label>>(x.t), ", ", ")");
peter klausler79d044e2018-03-01 00:56:101677 }
peter klausler8ea4a0a2018-04-06 20:13:201678 void Unparse(const PauseStmt &x) { Word("PAUSE"), Walk(" ", x.v); }
peter klausler79d044e2018-03-01 00:56:101679
Tim Keith9f755662018-03-23 21:31:141680#define WALK_NESTED_ENUM(CLASS, ENUM) \
peter klausler8ea4a0a2018-04-06 20:13:201681 void Unparse(const CLASS::ENUM &x) { Word(CLASS::EnumToString(x)); }
Tim Keith9f755662018-03-23 21:31:141682 WALK_NESTED_ENUM(AccessSpec, Kind) // R807
1683 WALK_NESTED_ENUM(TypeParamDefStmt, KindOrLen) // R734
1684 WALK_NESTED_ENUM(IntentSpec, Intent) // R826
1685 WALK_NESTED_ENUM(ImplicitStmt, ImplicitNoneNameSpec) // R866
1686 WALK_NESTED_ENUM(ConnectSpec::CharExpr, Kind) // R1205
1687 WALK_NESTED_ENUM(IoControlSpec::CharExpr, Kind)
1688 WALK_NESTED_ENUM(InquireSpec::CharVar, Kind)
1689 WALK_NESTED_ENUM(InquireSpec::IntVar, Kind)
1690 WALK_NESTED_ENUM(InquireSpec::LogVar, Kind)
1691 WALK_NESTED_ENUM(ProcedureStmt, Kind) // R1506
1692 WALK_NESTED_ENUM(UseStmt, ModuleNature) // R1410
peter klausler79d044e2018-03-01 00:56:101693#undef WALK_NESTED_ENUM
1694
1695 void Done() const { CHECK(indent_ == 0); }
1696
1697private:
1698 void Put(char);
1699 void Put(const char *);
1700 void Put(const std::string &);
peter klauslerb7cf5122018-03-14 22:31:161701 void PutKeywordLetter(char);
peter klausler79d044e2018-03-01 00:56:101702 void PutQuoted(const std::string &);
peter klauslerb7cf5122018-03-14 22:31:161703 void Word(const char *);
Tim Keith9f755662018-03-23 21:31:141704 void Word(const std::string &);
peter klausler79d044e2018-03-01 00:56:101705 void Indent() { indent_ += indentationAmount_; }
1706 void Outdent() {
1707 CHECK(indent_ >= indentationAmount_);
1708 indent_ -= indentationAmount_;
1709 }
1710
1711 // Call back to the traversal framework.
Tim Keith2af29bc2018-02-26 22:28:321712 template<typename T> void Walk(const T &x) {
1713 Fortran::parser::Walk(x, *this);
1714 }
1715
peter klausler79d044e2018-03-01 00:56:101716 // Traverse a std::optional<> value. Emit a prefix and/or a suffix string
1717 // only when it contains a value.
1718 template<typename A>
1719 void Walk(
1720 const char *prefix, const std::optional<A> &x, const char *suffix = "") {
1721 if (x.has_value()) {
peter klauslerb7cf5122018-03-14 22:31:161722 Word(prefix), Walk(*x), Word(suffix);
Tim Keith2af29bc2018-02-26 22:28:321723 }
1724 }
peter klausler79d044e2018-03-01 00:56:101725 template<typename A>
1726 void Walk(const std::optional<A> &x, const char *suffix = "") {
1727 return Walk("", x, suffix);
1728 }
1729
1730 // Traverse a std::list<>. Separate the elements with an optional string.
1731 // Emit a prefix and/or a suffix string only when the list is not empty.
1732 template<typename A>
1733 void Walk(const char *prefix, const std::list<A> &list,
1734 const char *comma = ", ", const char *suffix = "") {
1735 if (!list.empty()) {
1736 const char *str{prefix};
1737 for (const auto &x : list) {
peter klauslerb7cf5122018-03-14 22:31:161738 Word(str), Walk(x);
peter klausler79d044e2018-03-01 00:56:101739 str = comma;
1740 }
peter klauslerb7cf5122018-03-14 22:31:161741 Word(suffix);
peter klausler79d044e2018-03-01 00:56:101742 }
1743 }
1744 template<typename A>
1745 void Walk(const std::list<A> &list, const char *comma = ", ",
1746 const char *suffix = "") {
1747 return Walk("", list, comma, suffix);
1748 }
1749
1750 // Traverse a std::tuple<>, with an optional separator.
peter klausler424ec7b2018-03-20 17:59:071751 template<std::size_t J = 0, typename T>
peter klausler79d044e2018-03-01 00:56:101752 void WalkTupleElements(const T &tuple, const char *separator) {
1753 if constexpr (J < std::tuple_size_v<T>) {
1754 if (J > 0) {
peter klauslerb7cf5122018-03-14 22:31:161755 Word(separator);
peter klausler79d044e2018-03-01 00:56:101756 }
1757 Walk(std::get<J>(tuple));
1758 WalkTupleElements<J + 1>(tuple, separator);
1759 }
1760 }
1761 template<typename... A>
1762 void Walk(const std::tuple<A...> &tuple, const char *separator = "") {
1763 WalkTupleElements(tuple, separator);
1764 }
1765
peter klausler41d9cfd2018-04-03 17:29:041766 void EndSubprogram(const char *kind, const std::optional<Name> &name) {
1767 Outdent(), Word("END "), Word(kind), Walk(" ", name);
1768 structureComponents_.clear();
1769 }
peter klausler4e354d82018-03-30 22:23:371770
peter klausler79d044e2018-03-01 00:56:101771 std::ostream &out_;
1772 int indent_{0};
1773 const int indentationAmount_{1};
1774 int column_{1};
1775 const int maxColumns_{80};
peter klausler4e354d82018-03-30 22:23:371776 std::set<CharBlock> structureComponents_;
peter klausler79d044e2018-03-01 00:56:101777 Encoding encoding_{Encoding::UTF8};
peter klauslerb7cf5122018-03-14 22:31:161778 bool capitalizeKeywords_{true};
Tim Keith2af29bc2018-02-26 22:28:321779};
1780
peter klausler79d044e2018-03-01 00:56:101781void UnparseVisitor::Put(char ch) {
1782 if (column_ <= 1) {
1783 if (ch == '\n') {
1784 return;
1785 }
1786 for (int j{0}; j < indent_; ++j) {
1787 out_ << ' ';
1788 }
1789 column_ = indent_ + 2;
1790 } else if (ch == '\n') {
1791 column_ = 1;
1792 } else if (++column_ >= maxColumns_) {
1793 out_ << "&\n";
1794 for (int j{0}; j < indent_; ++j) {
1795 out_ << ' ';
1796 }
1797 out_ << '&';
1798 column_ = indent_ + 3;
1799 }
1800 out_ << ch;
Tim Keith2af29bc2018-02-26 22:28:321801}
1802
peter klausler79d044e2018-03-01 00:56:101803void UnparseVisitor::Put(const char *str) {
1804 for (; *str != '\0'; ++str) {
1805 Put(*str);
1806 }
1807}
1808
1809void UnparseVisitor::Put(const std::string &str) {
1810 for (char ch : str) {
1811 Put(ch);
1812 }
1813}
1814
peter klauslerb7cf5122018-03-14 22:31:161815void UnparseVisitor::PutKeywordLetter(char ch) {
1816 if (capitalizeKeywords_) {
peter klausler79d044e2018-03-01 00:56:101817 Put(ToUpperCaseLetter(ch));
peter klauslerb7cf5122018-03-14 22:31:161818 } else {
1819 Put(ToLowerCaseLetter(ch));
peter klausler79d044e2018-03-01 00:56:101820 }
1821}
1822
1823void UnparseVisitor::PutQuoted(const std::string &str) {
1824 Put('"');
1825 const auto emit = [&](char ch) { Put(ch); };
1826 for (char ch : str) {
1827 EmitQuotedChar(ch, emit, emit);
1828 }
1829 Put('"');
1830}
1831
peter klauslerb7cf5122018-03-14 22:31:161832void UnparseVisitor::Word(const char *str) {
1833 for (; *str != '\0'; ++str) {
1834 PutKeywordLetter(*str);
1835 }
1836}
1837
peter klausler75b29332018-03-23 22:14:521838void UnparseVisitor::Word(const std::string &str) { Word(str.c_str()); }
Tim Keith9f755662018-03-23 21:31:141839
peter klauslerb7cf5122018-03-14 22:31:161840void Unparse(std::ostream &out, const Program &program, Encoding encoding,
1841 bool capitalizeKeywords) {
1842 UnparseVisitor visitor{out, 1, encoding, capitalizeKeywords};
peter klausler79d044e2018-03-01 00:56:101843 Walk(program, visitor);
1844 visitor.Done();
1845}
Tim Keith2af29bc2018-02-26 22:28:321846} // namespace parser
1847} // namespace Fortran