[flang] Add format-specification.h.
authorpeter klausler <pklausler@nvidia.com>
Tue, 30 Jan 2018 19:51:15 +0000 (11:51 -0800)
committerpeter klausler <pklausler@nvidia.com>
Tue, 30 Jan 2018 19:51:15 +0000 (11:51 -0800)
Original-commit: flang-compiler/f18@7eea874fa421833d0d031c7bde7d573bc6dc37b7

flang/format-specification.h [new file with mode: 0644]

diff --git a/flang/format-specification.h b/flang/format-specification.h
new file mode 100644 (file)
index 0000000..7aa3085
--- /dev/null
@@ -0,0 +1,111 @@
+#ifndef FORTRAN_FORMAT_SPECIFICATION_H_
+#define FORTRAN_FORMAT_SPECIFICATION_H_
+
+// Represent parses of Fortran format specifications from FORMAT statements
+// and character literals in formatted I/O statements at compilation time
+// as well as from character variables and expressions at run time.
+// From requirement productions R1302-R1321 of the Fortran 2018 draft
+// standard (q.v.), extended with Hollerith.  These structures have been
+// isolated so that they may be used in the run-time without introducing
+// dependences on other parts of the compiler's source code.
+// TODO: support Q formatting extension?
+
+#include <cinttypes>
+#include <list>
+#include <optional>
+#include <string>
+#include <variant>
+
+namespace Fortran {
+
+// R1307 data-edit-desc (part 1 of 2) ->
+//         I w [. m] | B w [. m] | O w [. m] | Z w [. m] | F w . d |
+//         E w . d [E e] | EN w . d [E e] | ES w . d [E e] | EX w . d [E e] |
+//         G w [. d [E e]] | L w | A [w] | D w . d
+// R1308 w -> digit-string
+// R1309 m -> digit-string
+// R1310 d -> digit-string
+// R1311 e -> digit-string
+struct IntrinsicTypeDataEditDesc {
+  enum class Kind { I, B, O, Z, F, E, EN, ES, EX, G, L, A, D };
+  IntrinsicTypeDataEditDesc() = delete;
+  IntrinsicTypeDataEditDesc(IntrinsicTypeDataEditDesc &&) = default;
+  IntrinsicTypeDataEditDesc &operator=(IntrinsicTypeDataEditDesc &&) = default;
+  IntrinsicTypeDataEditDesc(Kind &&k, std::optional<int> &&w,
+                            std::optional<int> &&d, std::optional<int> &&e)
+    : kind{k}, width{std::move(w)}, digits{std::move(d)},
+      exponentWidth{std::move(e)} {}
+  Kind kind;
+  std::optional<int> width;  // w
+  std::optional<int> digits;  // m or d
+  std::optional<int> exponentWidth;  // e
+};
+
+// R1307 data-edit-desc (part 2 of 2) ->
+//         DT [char-literal-constant] [( v-list )]
+// R1312 v -> [sign] digit-string
+struct DerivedTypeDataEditDesc {
+  DerivedTypeDataEditDesc() = delete;
+  DerivedTypeDataEditDesc(DerivedTypeDataEditDesc &&) = default;
+  DerivedTypeDataEditDesc &operator=(DerivedTypeDataEditDesc &&) = default;
+  DerivedTypeDataEditDesc(std::string &&t, std::list<std::int64_t> &&p)
+    : type{std::move(t)}, parameters{std::move(p)} {}
+  std::string type;
+  std::list<std::int64_t> parameters;
+};
+
+// R1313 control-edit-desc ->
+//         position-edit-desc | [r] / | : | sign-edit-desc | k P |
+//         blank-interp-edit-desc | round-edit-desc | decimal-edit-desc
+// R1315 position-edit-desc -> T n | TL n | TR n | n X
+// R1316 n -> digit-string
+// R1317 sign-edit-desc -> SS | SP | S
+// R1318 blank-interp-edit-desc -> BN | BZ
+// R1319 round-edit-desc -> RU | RD | RZ | RN | RC | RP
+// R1320 decimal-edit-desc -> DC | DP
+struct ControlEditDesc {
+  enum class Kind { T, TL, TR, X, Slash, Colon, SS, SP, S, P, BN, BZ,
+                    RU, RD, RZ, RN, RC, RP, DC, DP };
+  ControlEditDesc() = delete;
+  ControlEditDesc(ControlEditDesc &&) = default;
+  ControlEditDesc &operator=(ControlEditDesc &&) = default;
+  explicit ControlEditDesc(Kind k) : kind{k} {}
+  ControlEditDesc(Kind k, int ct) : kind{k}, count{ct} {}
+  ControlEditDesc(int ct, Kind k) : kind{k}, count{ct} {}
+  Kind kind;
+  int count{1};  // r, k, or n
+};
+
+// R1304 format-item ->
+//         [r] data-edit-desc | control-edit-desc | char-string-edit-desc |
+//         [r] ( format-items )
+// R1306 r -> digit-string
+// R1321 char-string-edit-desc
+struct FormatItem {
+  FormatItem() = delete;
+  FormatItem(FormatItem &&) = default;
+  FormatItem &operator=(FormatItem &&) = default;
+  template<typename A> FormatItem(std::optional<int> &&r, A &&x)
+    : repeatCount{std::move(r)}, u{std::move(x)} {}
+  template<typename A> explicit FormatItem(A &&x) : u{std::move(x)} {}
+  std::optional<int> repeatCount;
+  std::variant<IntrinsicTypeDataEditDesc, DerivedTypeDataEditDesc,
+               ControlEditDesc, std::string, std::list<FormatItem>> u;
+};
+
+// R1302 format-specification ->
+//         ( [format-items] ) | ( [format-items ,] unlimited-format-item )
+// R1303 format-items -> format-item [[,] format-item]...
+// R1305 unlimited-format-item -> * ( format-items )
+struct FormatSpecification {
+  FormatSpecification() = delete;
+  FormatSpecification(FormatSpecification &&) = default;
+  FormatSpecification &operator=(FormatSpecification &&) = default;
+  explicit FormatSpecification(std::list<FormatItem> &&is)
+    : items(std::move(is)) {}
+  FormatSpecification(std::list<FormatItem> &&is, std::list<FormatItem> &&us)
+    : items(std::move(is)), unlimitedItems(std::move(us)) {}
+  std::list<FormatItem> items, unlimitedItems;
+};
+}  // namespace Fortran
+#endif  // FORTRAN_FORMAT_SPECIFICATION_H_