1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20/*!
21 * \file tvm/printer/doc.h
22 * \brief Doc ADT used for pretty printing.
23 *
24 * Reference: Philip Wadler. A Prettier Printer. Journal of Functional Programming'98
25 */
26#ifndef TVM_PRINTER_DOC_H_
27#define TVM_PRINTER_DOC_H_
28
29#include <tvm/node/node.h>
30#include <tvm/runtime/data_type.h>
31#include <tvm/runtime/object.h>
32
33#include <string>
34#include <type_traits>
35#include <vector>
36
37namespace tvm {
38
39/*!
40 * \brief Doc atom node for the ADT.
41 * \sa DocAtom
42 */
43class DocAtomNode : public Object {
44 public:
45 static constexpr const char* _type_key = "printer.DocAtom";
46 TVM_DECLARE_BASE_OBJECT_INFO(DocAtomNode, Object);
47};
48
49/*!
50 * \brief Managed reference to DocAtomNode.
51 * \sa DocAtomNode.
52 */
53class DocAtom : public ObjectRef {
54 public:
55 TVM_DEFINE_OBJECT_REF_METHODS(DocAtom, ObjectRef, DocAtomNode);
56};
57
58/*!
59 * \brief Stream-like interface for Doc DSL.
60 *
61 * The Doc DSL de-couples the layout decision from the printing decision.
62 *
63 * The layout(code formating) decisions include:
64 * - Change indentation.
65 * - Break single line into multiple ones(subjected to future improvements).
66 */
67class Doc {
68 public:
69 /*! \brief default constructor */
70 Doc() {}
71 /*!
72 * \brief Append right to the end of the current doc stream.
73 * \param right The doc to be appended.
74 * \return reference to self.
75 */
76 Doc& operator<<(const Doc& right);
77 /*!
78 * \brief Append right to the end of the current doc stream.
79 * \param right The doc to be appended.
80 * \return reference to self.
81 * \note pass by value to allow copy elison optimization.
82 */
83 Doc& operator<<(std::string right);
84 /*!
85 * \brief Append right to the end of the current doc stream.
86 * \param right The doc to be appended.
87 * \return reference to self.
88 */
89 Doc& operator<<(const DocAtom& right);
90 /*!
91 * \brief Convert value to string via std::ostreamstream
92 * the append to the current doc stream.
93 * \param right The doc to be appended.
94 * \tparam T the type of the value.
95 * \return reference to self.
96 */
97 template <typename T, typename = typename std::enable_if<!std::is_class<T>::value>::type>
98 Doc& operator<<(const T& value) {
99 std::ostringstream os;
100 os << value;
101 return *this << os.str();
102 }
103 /*!
104 * \brief Convert the doc stream into string.
105 * \return The string representation.
106 */
107 std::string str();
108 /*!
109 * \brief Create a doc that represents text content.
110 * \return The created doc.
111 */
112 static Doc Text(std::string value);
113 /*!
114 * \brief Create a doc that represents raw text(can have new lines)
115 * \return The created doc.
116 */
117 static Doc RawText(std::string value);
118 /*!
119 * \brief Create a doc that represents a new line.
120 * \return The created doc.
121 */
122 static Doc NewLine(int indent = 0);
123 /*!
124 * \brief Create a new doc that adds indentation to everyline of the doc.
125 * \param indent The indent to be added.
126 * \param doc The doc to be indented.
127 * \return The created doc.
128 * \note pass by value to allow copy elison optimization.
129 */
130 static Doc Indent(int indent, Doc doc);
131 /*!
132 * \brief Create a Doc that represents a string literal.
133 * \param value The content of the string literal.
134 * \param quote The quote in the literal.
135 * \return The created doc.
136 */
137 static Doc StrLiteral(const std::string& value, std::string quote = "\"");
138 /*!
139 * \brief Create a Doc that represents a boolean literal in python syntax.
140 * \param value The bool value.
141 * \return The created doc.
142 */
143 static Doc PyBoolLiteral(bool value);
144 /*!
145 * \brief Enclose body by brace and add indent.
146 * \param body The body
147 * \param open The open brace.
148 * \param close The close brace.
149 * \param indent amount of indentation.
150 * \return The created doc.
151 */
152 static Doc Brace(std::string open, const Doc& body, std::string close, int indent = 2);
153 /*!
154 * \brief Create a doc by concatenating together with separator.
155 * \param vec The docs to be concatenated.
156 * \param sep The seperator.
157 * \return The created doc.
158 */
159 static Doc Concat(const std::vector<Doc>& vec, const Doc& sep = Text(", "));
160
161 private:
162 /*! \brief Internal doc stream. */
163 std::vector<DocAtom> stream_;
164};
165
166} // namespace tvm
167#endif // TVM_PRINTER_DOC_H_
168