blob: dc6ba8952f3e4f5f02ca30c1aad8473e292393b5 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*!
* \file tvm/printer/doc.h
* \brief Doc ADT used for pretty printing.
*
* Reference: Philip Wadler. A Prettier Printer. Journal of Functional Programming'98
*/
#ifndef TVM_PRINTER_DOC_H_
#define TVM_PRINTER_DOC_H_
#include <tvm/node/node.h>
#include <tvm/runtime/data_type.h>
#include <tvm/runtime/object.h>
#include <string>
#include <type_traits>
#include <vector>
namespace tvm {
/*!
* \brief Doc atom node for the ADT.
* \sa DocAtom
*/
class DocAtomNode : public Object {
public:
static constexpr const char* _type_key = "printer.DocAtom";
TVM_DECLARE_BASE_OBJECT_INFO(DocAtomNode, Object);
};
/*!
* \brief Managed reference to DocAtomNode.
* \sa DocAtomNode.
*/
class DocAtom : public ObjectRef {
public:
TVM_DEFINE_OBJECT_REF_METHODS(DocAtom, ObjectRef, DocAtomNode);
};
/*!
* \brief Stream-like interface for Doc DSL.
*
* The Doc DSL de-couples the layout decision from the printing decision.
*
* The layout(code formating) decisions include:
* - Change indentation.
* - Break single line into multiple ones(subjected to future improvements).
*/
class Doc {
public:
/*! \brief default constructor */
Doc() {}
/*!
* \brief Append right to the end of the current doc stream.
* \param right The doc to be appended.
* \return reference to self.
*/
Doc& operator<<(const Doc& right);
/*!
* \brief Append right to the end of the current doc stream.
* \param right The doc to be appended.
* \return reference to self.
* \note pass by value to allow copy elison optimization.
*/
Doc& operator<<(std::string right);
/*!
* \brief Append right to the end of the current doc stream.
* \param right The doc to be appended.
* \return reference to self.
*/
Doc& operator<<(const DocAtom& right);
/*!
* \brief Convert value to string via std::ostreamstream
* the append to the current doc stream.
* \param right The doc to be appended.
* \tparam T the type of the value.
* \return reference to self.
*/
template <typename T, typename = typename std::enable_if<!std::is_class<T>::value>::type>
Doc& operator<<(const T& value) {
std::ostringstream os;
os << value;
return *this << os.str();
}
/*!
* \brief Convert the doc stream into string.
* \return The string representation.
*/
std::string str();
/*!
* \brief Create a doc that represents text content.
* \return The created doc.
*/
static Doc Text(std::string value);
/*!
* \brief Create a doc that represents raw text(can have new lines)
* \return The created doc.
*/
static Doc RawText(std::string value);
/*!
* \brief Create a doc that represents a new line.
* \return The created doc.
*/
static Doc NewLine(int indent = 0);
/*!
* \brief Create a new doc that adds indentation to everyline of the doc.
* \param indent The indent to be added.
* \param doc The doc to be indented.
* \return The created doc.
* \note pass by value to allow copy elison optimization.
*/
static Doc Indent(int indent, Doc doc);
/*!
* \brief Create a Doc that represents a string literal.
* \param value The content of the string literal.
* \param quote The quote in the literal.
* \return The created doc.
*/
static Doc StrLiteral(const std::string& value, std::string quote = "\"");
/*!
* \brief Create a Doc that represents a boolean literal in python syntax.
* \param value The bool value.
* \return The created doc.
*/
static Doc PyBoolLiteral(bool value);
/*!
* \brief Enclose body by brace and add indent.
* \param body The body
* \param open The open brace.
* \param close The close brace.
* \param indent amount of indentation.
* \return The created doc.
*/
static Doc Brace(std::string open, const Doc& body, std::string close, int indent = 2);
/*!
* \brief Create a doc by concatenating together with separator.
* \param vec The docs to be concatenated.
* \param sep The seperator.
* \return The created doc.
*/
static Doc Concat(const std::vector<Doc>& vec, const Doc& sep = Text(", "));
private:
/*! \brief Internal doc stream. */
std::vector<DocAtom> stream_;
};
} // namespace tvm
#endif // TVM_PRINTER_DOC_H_