summaryrefslogtreecommitdiff
path: root/src/dump_as_rust.cpp
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-10-23 14:25:34 +0800
committerJohn Hodge <tpg@mutabah.net>2016-10-23 14:25:34 +0800
commitdfec5021812ae61d56fc376f7556726d79c4d48e (patch)
tree74caa3a37e4ab02ff7ea02c1ff6e2eb317ee8f74 /src/dump_as_rust.cpp
parentd5fb66ba18c8684a55e32570c12bcd4ed1bb6d5a (diff)
downloadmrust-dfec5021812ae61d56fc376f7556726d79c4d48e.tar.gz
AST - (minor) Move dump_as_rust to ast/dump.cpp
Diffstat (limited to 'src/dump_as_rust.cpp')
-rw-r--r--src/dump_as_rust.cpp1098
1 files changed, 0 insertions, 1098 deletions
diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp
deleted file mode 100644
index 401cc63e..00000000
--- a/src/dump_as_rust.cpp
+++ /dev/null
@@ -1,1098 +0,0 @@
-/*
- * MRustC - Mutabah's Rust Compiler
- * - By John Hodge (Mutabah/thePowersGang)
- *
- * dump_as_rust.cpp
- * - Dumps the AST of a crate as rust code (annotated)
- */
-#include "ast/crate.hpp"
-#include "ast/ast.hpp"
-#include "ast/expr.hpp"
-#include <main_bindings.hpp>
-
-#include <cpp_unpack.h>
-
-#define IS(v, c) (dynamic_cast<c*>(&v) != 0)
-#define WRAPIF_CMD(v, t) || IS(v, t)
-#define WRAPIF(uniq_ptr, class1, ...) do { auto& _v = *(uniq_ptr); if( IS(_v, class1) CC_ITERATE(WRAPIF_CMD, (_v), __VA_ARGS__) ) { paren_wrap(uniq_ptr); } else { AST::NodeVisitor::visit(uniq_ptr); } } while(0)
-
-class RustPrinter:
- public AST::NodeVisitor
-{
- ::std::ostream& m_os;
- int m_indent_level;
- bool m_expr_root; //!< used to allow 'if' and 'match' to behave differently as standalone exprs
-public:
- RustPrinter(::std::ostream& os):
- m_os(os),
- m_indent_level(0),
- m_expr_root(false)
- {}
-
- void handle_module(const AST::Module& mod);
- void handle_struct(const AST::Struct& s);
- void handle_enum(const AST::Enum& s);
- void handle_trait(const AST::Trait& s);
-
- void handle_function(bool is_pub, const ::std::string& name, const AST::Function& f);
-
- virtual bool is_const() const override { return true; }
- virtual void visit(AST::ExprNode_Block& n) override {
- if( n.m_is_unsafe ) {
- m_os << "unsafe ";
- }
- m_os << "{";
- inc_indent();
- if( n.m_local_mod )
- {
- handle_module(*n.m_local_mod);
- }
- bool is_first = true;
- for( auto& child : n.m_nodes )
- {
- if(is_first) {
- is_first = false;
- } else {
- m_os << ";";
- }
- m_os << "\n";
- m_os << indent();
- m_expr_root = true;
- if( !child.get() )
- m_os << "/* nil */";
- else
- AST::NodeVisitor::visit(child);
- }
- if( !n.m_yields_final_value )
- m_os << ";";
- m_os << "\n";
- dec_indent();
- m_os << indent() << "}";
- }
- virtual void visit(AST::ExprNode_Macro& n) override {
- m_expr_root = false;
- m_os << n.m_name << "!( /* TODO: Macro TT */ )";
- }
- virtual void visit(AST::ExprNode_Flow& n) override {
- m_expr_root = false;
- switch(n.m_type)
- {
- case AST::ExprNode_Flow::RETURN: m_os << "return "; break;
- case AST::ExprNode_Flow::BREAK: m_os << "break "; break;
- case AST::ExprNode_Flow::CONTINUE: m_os << "continue "; break;
- }
- AST::NodeVisitor::visit(n.m_value);
- }
- virtual void visit(AST::ExprNode_LetBinding& n) override {
- m_expr_root = false;
- m_os << "let ";
- print_pattern(n.m_pat, false);
- m_os << ": ";
- print_type(n.m_type);
- m_os << " = ";
- AST::NodeVisitor::visit(n.m_value);
- }
- virtual void visit(AST::ExprNode_Assign& n) override {
- m_expr_root = false;
- AST::NodeVisitor::visit(n.m_slot);
- switch(n.m_op)
- {
- case AST::ExprNode_Assign::NONE: m_os << " = "; break;
- case AST::ExprNode_Assign::ADD: m_os << " += "; break;
- case AST::ExprNode_Assign::SUB: m_os << " -= "; break;
- case AST::ExprNode_Assign::MUL: m_os << " *= "; break;
- case AST::ExprNode_Assign::DIV: m_os << " /= "; break;
- case AST::ExprNode_Assign::MOD: m_os << " %= "; break;
- case AST::ExprNode_Assign::AND: m_os << " &= "; break;
- case AST::ExprNode_Assign::OR: m_os << " |= "; break;
- case AST::ExprNode_Assign::XOR: m_os << " ^= "; break;
- case AST::ExprNode_Assign::SHR: m_os << " >>= "; break;
- case AST::ExprNode_Assign::SHL: m_os << " <<= "; break;
- }
- AST::NodeVisitor::visit(n.m_value);
- }
- virtual void visit(AST::ExprNode_CallPath& n) override {
- m_expr_root = false;
- m_os << n.m_path;
- m_os << "(";
- bool is_first = true;
- for( auto& arg : n.m_args )
- {
- if(is_first) {
- is_first = false;
- } else {
- m_os << ", ";
- }
- AST::NodeVisitor::visit(arg);
- }
- m_os << ")";
- }
- virtual void visit(AST::ExprNode_CallMethod& n) override {
- m_expr_root = false;
- WRAPIF( n.m_val
- , AST::ExprNode_Deref, AST::ExprNode_UniOp
- , AST::ExprNode_Cast, AST::ExprNode_BinOp, AST::ExprNode_Assign
- , AST::ExprNode_Match, AST::ExprNode_If, AST::ExprNode_IfLet, AST::ExprNode_Match
- );
- m_os << "." << n.m_method;
- m_os << "(";
- bool is_first = true;
- for( auto& arg : n.m_args )
- {
- if(is_first) {
- is_first = false;
- } else {
- m_os << ", ";
- }
- AST::NodeVisitor::visit(arg);
- }
- m_os << ")";
- }
- virtual void visit(AST::ExprNode_CallObject& n) override {
- m_expr_root = false;
- m_os << "(";
- AST::NodeVisitor::visit(n.m_val);
- m_os << ")(";
- bool is_first = true;
- for( auto& arg : n.m_args )
- {
- if(is_first) {
- is_first = false;
- } else {
- m_os << ", ";
- }
- AST::NodeVisitor::visit(arg);
- }
- m_os << ")";
- }
- virtual void visit(AST::ExprNode_Loop& n) override {
- bool expr_root = m_expr_root;
- m_expr_root = false;
-
- switch(n.m_type)
- {
- case AST::ExprNode_Loop::LOOP:
- m_os << "loop";
- break;
- case AST::ExprNode_Loop::WHILE:
- m_os << "while ";
- AST::NodeVisitor::visit(n.m_cond);
- break;
- case AST::ExprNode_Loop::WHILELET:
- m_os << "while let ";
- print_pattern(n.m_pattern, true);
- m_os << " = ";
- AST::NodeVisitor::visit(n.m_cond);
- break;
- case AST::ExprNode_Loop::FOR:
- m_os << "while for ";
- print_pattern(n.m_pattern, true);
- m_os << " in ";
- AST::NodeVisitor::visit(n.m_cond);
- break;
- }
-
- if( expr_root )
- {
- m_os << "\n";
- m_os << indent();
- }
- else
- {
- m_os << " ";
- }
-
- AST::NodeVisitor::visit(n.m_code);
- }
- virtual void visit(AST::ExprNode_Match& n) override {
- bool expr_root = m_expr_root;
- m_expr_root = false;
- m_os << "match ";
- AST::NodeVisitor::visit(n.m_val);
-
- if(expr_root)
- {
- m_os << "\n";
- m_os << indent() << "{\n";
- }
- else
- {
- m_os << " {\n";
- inc_indent();
- }
-
- for( auto& arm : n.m_arms )
- {
- m_os << indent();
- bool is_first = true;
- for( const auto& pat : arm.m_patterns ) {
- if(!is_first)
- m_os << "|";
- is_first = false;
- print_pattern(pat, true);
- }
- if( arm.m_cond )
- {
- m_os << " if ";
- AST::NodeVisitor::visit(arm.m_cond);
- }
- m_os << " => ";
- // Increase indent, but don't print. Causes nested blocks to be indented above the match
- inc_indent();
- AST::NodeVisitor::visit(arm.m_code);
- dec_indent();
- m_os << ",\n";
- }
-
- if(expr_root)
- {
- m_os << indent() << "}";
- }
- else
- {
- m_os << indent() << "}";
- dec_indent();
- }
- }
- virtual void visit(AST::ExprNode_If& n) override {
- bool expr_root = m_expr_root;
- m_expr_root = false;
- m_os << "if ";
- AST::NodeVisitor::visit(n.m_cond);
-
- visit_if_common(expr_root, n.m_true, n.m_false);
- }
- virtual void visit(AST::ExprNode_IfLet& n) override {
- bool expr_root = m_expr_root;
- m_expr_root = false;
- m_os << "if let ";
- print_pattern(n.m_pattern, true);
- m_os << " = ";
- AST::NodeVisitor::visit(n.m_value);
-
- visit_if_common(expr_root, n.m_true, n.m_false);
- }
- void visit_if_common(bool expr_root, const ::std::unique_ptr<AST::ExprNode>& tv, const ::std::unique_ptr<AST::ExprNode>& fv)
- {
- if( expr_root )
- {
- m_os << "\n";
- m_os << indent();
- }
- else
- {
- m_os << " ";
- }
-
- bool is_block = (dynamic_cast<const AST::ExprNode_Block*>(&*tv) != nullptr);
- if( !is_block ) m_os << "{ ";
- AST::NodeVisitor::visit(tv);
- if( !is_block ) m_os << " }";
- if(fv.get())
- {
- if( expr_root )
- {
- m_os << "\n";
- m_os << indent() << "else";
- // handle chained if statements nicely
- if( IS(*fv, AST::ExprNode_If) || IS(*fv, AST::ExprNode_IfLet) ) {
- m_expr_root = true;
- m_os << " ";
- }
- else
- m_os << "\n" << indent();
- }
- else
- {
- m_os << " else ";
- }
- AST::NodeVisitor::visit(fv);
- }
- }
- virtual void visit(AST::ExprNode_Closure& n) override {
- m_expr_root = false;
- m_os << "|";
- bool is_first = true;
- for( const auto& arg : n.m_args )
- {
- if(!is_first) m_os << ", ";
- is_first = false;
- print_pattern(arg.first, false);
- m_os << ": ";
- print_type(arg.second);
- }
- m_os << "| ->";
- print_type(n.m_return);
- m_os << " ";
- AST::NodeVisitor::visit(n.m_code);
- }
- virtual void visit(AST::ExprNode_Integer& n) override {
- m_expr_root = false;
- switch(n.m_datatype)
- {
- case CORETYPE_INVAL: break;
- case CORETYPE_BOOL:
- case CORETYPE_STR:
- break;
- case CORETYPE_CHAR:
- m_os << "'\\u{" << ::std::hex << n.m_value << ::std::dec << "}'";
- break;
- case CORETYPE_F32:
- case CORETYPE_F64:
- break;
- case CORETYPE_U8:
- case CORETYPE_U16:
- case CORETYPE_U32:
- case CORETYPE_U64:
- case CORETYPE_UINT:
- case CORETYPE_ANY:
- m_os << "0x" << ::std::hex << n.m_value << ::std::dec;
- break;
- case CORETYPE_I8:
- case CORETYPE_I16:
- case CORETYPE_I32:
- case CORETYPE_I64:
- case CORETYPE_INT:
- m_os << (int64_t)n.m_value;
- //m_os << "0x" << ::std::hex << n.m_value << ::std::dec;
- break;
- }
- }
- virtual void visit(AST::ExprNode_Float& n) override {
- m_expr_root = false;
- switch(n.m_datatype)
- {
- case CORETYPE_ANY:
- case CORETYPE_F32:
- case CORETYPE_F64:
- m_os.precision(10);
- m_os << n.m_value;
- break;
- default:
- break;
- }
- }
- virtual void visit(AST::ExprNode_Bool& n) override {
- m_expr_root = false;
- if( n.m_value )
- m_os << "true";
- else
- m_os << "false";
- }
- virtual void visit(AST::ExprNode_String& n) override {
- m_expr_root = false;
- m_os << "\"" << n.m_value << "\"";
- }
- virtual void visit(AST::ExprNode_ByteString& n) override {
- m_expr_root = false;
- m_os << "b\"" << n.m_value << "\"";
- }
-
- virtual void visit(AST::ExprNode_StructLiteral& n) override {
- m_expr_root = false;
- m_os << n.m_path << " {\n";
- inc_indent();
- for( const auto& i : n.m_values )
- {
- m_os << indent() << i.first << ": ";
- AST::NodeVisitor::visit(i.second);
- m_os << ",\n";
- }
- if( n.m_base_value.get() )
- {
- m_os << indent() << ".. ";
- AST::NodeVisitor::visit(n.m_base_value);
- m_os << "\n";
- }
- m_os << indent() << "}";
- dec_indent();
- }
- virtual void visit(AST::ExprNode_Array& n) override {
- m_expr_root = false;
- m_os << "[";
- if( n.m_size.get() )
- {
- AST::NodeVisitor::visit(n.m_values[0]);
- m_os << "; ";
- AST::NodeVisitor::visit(n.m_size);
- }
- else {
- for( auto& item : n.m_values )
- {
- AST::NodeVisitor::visit(item);
- m_os << ", ";
- }
- }
- m_os << "]";
- }
- virtual void visit(AST::ExprNode_Tuple& n) override {
- m_expr_root = false;
- m_os << "(";
- for( auto& item : n.m_values )
- {
- AST::NodeVisitor::visit(item);
- m_os << ", ";
- }
- m_os << ")";
- }
- virtual void visit(AST::ExprNode_NamedValue& n) override {
- m_expr_root = false;
- m_os << n.m_path;
- }
- virtual void visit(AST::ExprNode_Field& n) override {
- m_expr_root = false;
- WRAPIF( n.m_obj
- , AST::ExprNode_Deref, AST::ExprNode_UniOp
- , AST::ExprNode_Cast, AST::ExprNode_BinOp, AST::ExprNode_Assign
- , AST::ExprNode_Match, AST::ExprNode_If, AST::ExprNode_IfLet, AST::ExprNode_Match
- );
- m_os << "." << n.m_name;
- }
- virtual void visit(AST::ExprNode_Index& n) override {
- m_expr_root = false;
- WRAPIF( n.m_obj
- , AST::ExprNode_Deref, AST::ExprNode_UniOp
- , AST::ExprNode_Cast, AST::ExprNode_BinOp, AST::ExprNode_Assign
- , AST::ExprNode_Match, AST::ExprNode_If, AST::ExprNode_IfLet, AST::ExprNode_Match
- );
- m_os << "[";
- AST::NodeVisitor::visit(n.m_idx);
- m_os << "]";
- }
- virtual void visit(AST::ExprNode_Deref& n) override {
- m_expr_root = false;
- m_os << "*(";
- AST::NodeVisitor::visit(n.m_value);
- m_os << ")";
- }
- virtual void visit(AST::ExprNode_Cast& n) override {
- m_expr_root = false;
- AST::NodeVisitor::visit(n.m_value);
- m_os << " as " << n.m_type;
- }
- virtual void visit(AST::ExprNode_BinOp& n) override {
- m_expr_root = false;
- WRAPIF(n.m_left
- , AST::ExprNode_Cast, AST::ExprNode_BinOp
- );
- m_os << " ";
- switch(n.m_type)
- {
- case AST::ExprNode_BinOp::CMPEQU: m_os << "=="; break;
- case AST::ExprNode_BinOp::CMPNEQU:m_os << "!="; break;
- case AST::ExprNode_BinOp::CMPLT: m_os << "<"; break;
- case AST::ExprNode_BinOp::CMPLTE: m_os << "<="; break;
- case AST::ExprNode_BinOp::CMPGT: m_os << ">"; break;
- case AST::ExprNode_BinOp::CMPGTE: m_os << ">="; break;
- case AST::ExprNode_BinOp::BOOLAND:m_os << "&&"; break;
- case AST::ExprNode_BinOp::BOOLOR: m_os << "||"; break;
- case AST::ExprNode_BinOp::BITAND: m_os << "&"; break;
- case AST::ExprNode_BinOp::BITOR: m_os << "|"; break;
- case AST::ExprNode_BinOp::BITXOR: m_os << "^"; break;
- case AST::ExprNode_BinOp::SHL: m_os << "<<"; break;
- case AST::ExprNode_BinOp::SHR: m_os << ">>"; break;
- case AST::ExprNode_BinOp::MULTIPLY: m_os << "*"; break;
- case AST::ExprNode_BinOp::DIVIDE: m_os << "/"; break;
- case AST::ExprNode_BinOp::MODULO: m_os << "%"; break;
- case AST::ExprNode_BinOp::ADD: m_os << "+"; break;
- case AST::ExprNode_BinOp::SUB: m_os << "-"; break;
- case AST::ExprNode_BinOp::RANGE: m_os << ".."; break;
- case AST::ExprNode_BinOp::RANGE_INC: m_os << "..."; break;
- case AST::ExprNode_BinOp::PLACE_IN: m_os << "<-"; break;
- }
- m_os << " ";
- if( IS(*n.m_right, AST::ExprNode_BinOp) )
- paren_wrap(n.m_right);
- else
- AST::NodeVisitor::visit(n.m_right);
- }
- virtual void visit(AST::ExprNode_UniOp& n) override {
- m_expr_root = false;
- switch(n.m_type)
- {
- case AST::ExprNode_UniOp::NEGATE: m_os << "-"; break;
- case AST::ExprNode_UniOp::INVERT: m_os << "!"; break;
- case AST::ExprNode_UniOp::BOX: m_os << "box "; break;
- case AST::ExprNode_UniOp::REF: m_os << "&"; break;
- case AST::ExprNode_UniOp::REFMUT: m_os << "&mut "; break;
- case AST::ExprNode_UniOp::QMARK: break;
- }
-
- if( IS(*n.m_value, AST::ExprNode_BinOp) )
- m_os << "(";
- AST::NodeVisitor::visit(n.m_value);
- if( IS(*n.m_value, AST::ExprNode_BinOp) )
- m_os << ")";
- switch(n.m_type)
- {
- case AST::ExprNode_UniOp::QMARK: m_os << "?"; break;
- default: break;
- }
- }
-
-
-private:
- void paren_wrap(::std::unique_ptr<AST::ExprNode>& node) {
- m_os << "(";
- AST::NodeVisitor::visit(node);
- m_os << ")";
- }
-
- void print_attrs(const AST::MetaItems& attrs);
- void print_params(const AST::GenericParams& params);
- void print_bounds(const AST::GenericParams& params);
- void print_pattern_tuple(const AST::Pattern::TuplePat& v, bool is_refutable);
- void print_pattern(const AST::Pattern& p, bool is_refutable);
- void print_type(const TypeRef& t);
-
- void inc_indent();
- RepeatLitStr indent();
- void dec_indent();
-};
-
-void Dump_Rust(const char *Filename, const AST::Crate& crate)
-{
- ::std::ofstream os(Filename);
- RustPrinter printer(os);
- printer.handle_module(crate.root_module());
-}
-
-void RustPrinter::print_attrs(const AST::MetaItems& attrs)
-{
- for(const auto& a : attrs.m_items)
- {
- m_os << indent() << "#[" << a << "]\n";
- }
-}
-
-void RustPrinter::handle_module(const AST::Module& mod)
-{
- bool need_nl = true;
-
- for( const auto& i : mod.items() )
- {
- if( !i.data.is_Use() ) continue ;
- const auto& i_data = i.data.as_Use();
- //if(need_nl) {
- // m_os << "\n";
- // need_nl = false;
- //}
- if( i_data.path == AST::Path() ) {
- continue ;
- }
- m_os << indent() << (i.is_pub ? "pub " : "") << "use " << i_data;
- if( i.name == "" )
- {
- m_os << "::*";
- }
- else if( i_data.path.nodes().back().name() != i.name )
- {
- m_os << " as " << i.name;
- }
- m_os << ";\n";
- }
- need_nl = true;
-
- for( const auto& item : mod.items() )
- {
- if( !item.data.is_Module() ) continue ;
- const auto& e = item.data.as_Module();
-
- m_os << "\n";
- m_os << indent() << (item.is_pub ? "pub " : "") << "mod " << item.name << "\n";
- m_os << indent() << "{\n";
- inc_indent();
- handle_module(e);
- dec_indent();
- m_os << indent() << "}\n";
- m_os << "\n";
- }
-
- for( const auto& item : mod.items() )
- {
- if( !item.data.is_Type() ) continue ;
- const auto& e = item.data.as_Type();
-
- if(need_nl) {
- m_os << "\n";
- need_nl = false;
- }
- print_attrs(item.data.attrs);
- m_os << indent() << (item.is_pub ? "pub " : "") << "type " << item.name;
- print_params(e.params());
- m_os << " = " << e.type();
- print_bounds(e.params());
- m_os << ";\n";
- }
- need_nl = true;
-
- for( const auto& item : mod.items() )
- {
- if( !item.data.is_Struct() ) continue ;
- const auto& e = item.data.as_Struct();
-
- m_os << "\n";
- print_attrs(item.data.attrs);
- m_os << indent() << (item.is_pub ? "pub " : "") << "struct " << item.name;
- handle_struct(e);
- }
-
- for( const auto& item : mod.items() )
- {
- if( !item.data.is_Enum() ) continue ;
- const auto& e = item.data.as_Enum();
-
- m_os << "\n";
- print_attrs(item.data.attrs);
- m_os << indent() << (item.is_pub ? "pub " : "") << "enum " << item.name;
- handle_enum(e);
- }
-
- for( const auto& item : mod.items() )
- {
- if( !item.data.is_Trait() ) continue ;
- const auto& e = item.data.as_Trait();
-
- m_os << "\n";
- print_attrs(item.data.attrs);
- m_os << indent() << (item.is_pub ? "pub " : "") << "trait " << item.name;
- handle_trait(e);
- }
-
- for( const auto& item : mod.items() )
- {
- if( !item.data.is_Static() ) continue ;
- const auto& e = item.data.as_Static();
-
- if(need_nl) {
- m_os << "\n";
- need_nl = false;
- }
- print_attrs(item.data.attrs);
- m_os << indent() << (item.is_pub ? "pub " : "");
- switch( e.s_class() )
- {
- case AST::Static::CONST: m_os << "const "; break;
- case AST::Static::STATIC: m_os << "static "; break;
- case AST::Static::MUT: m_os << "static mut "; break;
- }
- m_os << item.name << ": " << e.type() << " = ";
- e.value().visit_nodes(*this);
- m_os << ";\n";
- }
-
- for( const auto& item : mod.items() )
- {
- if( !item.data.is_Function() ) continue ;
- const auto& e = item.data.as_Function();
-
- m_os << "\n";
- print_attrs(item.data.attrs);
- handle_function(item.is_pub, item.name, e);
- }
-
- for( const auto& i : mod.impls() )
- {
- m_os << "\n";
- m_os << indent() << "impl";
- print_params(i.def().params());
- if( i.def().trait().ent != AST::Path() )
- {
- m_os << " " << i.def().trait().ent << " for";
- }
- m_os << " " << i.def().type() << "\n";
-
- print_bounds(i.def().params());
- m_os << indent() << "{\n";
- inc_indent();
- for( const auto& it : i.items() )
- {
- TU_MATCH_DEF(AST::Item, (*it.data), (e),
- (
- throw ::std::runtime_error(FMT("Unexpected item type in impl block - " << it.data->tag_str()));
- ),
- (None,
- // Ignore, it's been deleted by #[cfg]
- ),
- (MacroInv,
- // TODO: Dump macro invocations
- ),
- (Static,
- m_os << indent();
- switch(e.s_class())
- {
- case ::AST::Static::CONST: m_os << "const "; break;
- case ::AST::Static::STATIC: m_os << "static "; break;
- case ::AST::Static::MUT: m_os << "static mut "; break;
- }
- m_os << it.name << ": " << e.type() << " = ";
- e.value().visit_nodes(*this);
- m_os << ";\n";
- ),
- (Type,
- m_os << indent() << "type " << it.name << " = " << e.type() << ";\n";
- ),
- (Function,
- handle_function(it.is_pub, it.name, e);
- )
- )
- }
- dec_indent();
- m_os << indent() << "}\n";
- }
-}
-
-void RustPrinter::print_params(const AST::GenericParams& params)
-{
- if( params.ty_params().size() > 0 || params.lft_params().size() > 0 )
- {
- bool is_first = true;
- m_os << "<";
- // Lifetimes
- for( const auto& p : params.lft_params() )
- {
- if( !is_first )
- m_os << ", ";
- m_os << "'" << p;
- is_first = false;
- }
- // Types
- for( const auto& p : params.ty_params() )
- {
- if( !is_first )
- m_os << ", ";
- m_os << p.name();
- if( !p.get_default().is_wildcard() )
- m_os << " = " << p.get_default();
- is_first = false;
- }
- m_os << ">";
- }
-}
-
-void RustPrinter::print_bounds(const AST::GenericParams& params)
-{
- if( params.bounds().size() )
- {
- m_os << indent() << "where\n";
- inc_indent();
- bool is_first = true;
-
- for( const auto& b : params.bounds() )
- {
- if( !is_first )
- m_os << ",\n";
- is_first = false;
-
- m_os << indent();
- TU_MATCH(AST::GenericBound, (b), (ent),
- (Lifetime,
- m_os << "'" << ent.test << ": '" << ent.bound;
- ),
- (TypeLifetime,
- m_os << ent.type << ": '" << ent.bound;
- ),
- (IsTrait,
- if( ent.hrls.size() > 0 ) {
- m_os << "for<'" << ::join(", '", ent.hrls) << "> ";
- }
- m_os << ent.type << ": " << ent.trait;
- ),
- (MaybeTrait,
- m_os << ent.type << ": ?" << ent.trait;
- ),
- (NotTrait,
- m_os << ent.type << ": !" << ent.trait;
- ),
- (Equality,
- m_os << ent.type << ": =" << ent.replacement;
- )
- )
- }
- m_os << "\n";
-
- dec_indent();
- }
-}
-
-void RustPrinter::print_pattern_tuple(const AST::Pattern::TuplePat& v, bool is_refutable)
-{
- for(const auto& sp : v.start) {
- print_pattern(sp, is_refutable);
- m_os << ", ";
- }
- if( v.has_wildcard )
- {
- m_os << ".., ";
- for(const auto& sp : v.end) {
- print_pattern(sp, is_refutable);
- m_os << ", ";
- }
- }
-}
-void RustPrinter::print_pattern(const AST::Pattern& p, bool is_refutable)
-{
- if( p.binding().is_valid() ) {
- if( p.binding().m_mutable )
- m_os << "mut ";
- switch(p.binding().m_type)
- {
- case ::AST::PatternBinding::Type::MOVE:
- break;
- case ::AST::PatternBinding::Type::REF:
- m_os << "ref ";
- break;
- case ::AST::PatternBinding::Type::MUTREF:
- m_os << "ref mut ";
- break;
- }
- m_os << p.binding().m_name << "/*"<<p.binding().m_slot<<"*/";
- // If binding is irrefutable, and would be binding against a wildcard, just emit the name
- if( !is_refutable && p.data().is_Any() )
- {
- return ;
- }
- m_os << " @ ";
- }
- TU_MATCH(AST::Pattern::Data, (p.data()), (v),
- (Any,
- m_os << "_";
- ),
- (MaybeBind,
- m_os << "_ /*?*/";
- ),
- (Macro,
- m_os << *v.inv;
- ),
- (Box, {
- const auto& v = p.data().as_Box();
- m_os << "& ";
- print_pattern(*v.sub, is_refutable);
- }),
- (Ref, {
- const auto& v = p.data().as_Ref();
- if(v.mut)
- m_os << "&mut ";
- else
- m_os << "& ";
- print_pattern(*v.sub, is_refutable);
- }),
- (Value,
- m_os << v.start;
- if( ! v.end.is_Invalid() ) {
- m_os << " ... " << v.end;
- }
- ),
- (StructTuple,
- m_os << v.path << "(";
- this->print_pattern_tuple(v.tup_pat, is_refutable);
- m_os << ")";
- ),
- (Struct, {
- const auto& v = p.data().as_Struct();
- m_os << v.path << "(";
- for(const auto& sp : v.sub_patterns) {
- m_os << sp.first << ": ";
- print_pattern(sp.second, is_refutable);
- m_os << ",";
- }
- m_os << ")";
- }),
- (Tuple,
- m_os << "(";
- this->print_pattern_tuple(v, is_refutable);
- m_os << ")";
- ),
- (Slice,
- m_os << "[";
- bool needs_comma = false;
- if(v.leading.size()) {
- m_os << v.leading;
- needs_comma = true;
- }
- if(v.extra_bind.size() > 0) {
- if( needs_comma ) {
- m_os << ", ";
- }
- if(v.extra_bind != "_")
- m_os << v.extra_bind;
- m_os << "..";
- needs_comma = true;
- }
- if(v.trailing.size()) {
- if( needs_comma ) {
- m_os << ", ";
- }
- m_os << v.trailing;
- }
- m_os << "]";
- )
- )
-}
-
-void RustPrinter::print_type(const TypeRef& t)
-{
- m_os << t;
-}
-
-void RustPrinter::handle_struct(const AST::Struct& s)
-{
- print_params(s.params());
-
- TU_MATCH(AST::StructData, (s.m_data), (e),
- (Tuple,
- if( e.ents.size() == 0 )
- {
- m_os << " /* unit-like */\n";
- print_bounds(s.params());
- m_os << indent() << ";\n";
- }
- else
- {
- m_os << "(";
- for( const auto& i : e.ents )
- m_os << i.m_type << ", ";
- m_os << ")\n";
- print_bounds(s.params());
- m_os << indent() << ";\n";
- }
- ),
- (Struct,
- m_os << "\n";
- print_bounds(s.params());
-
- m_os << indent() << "{\n";
- inc_indent();
- for( const auto& i : e.ents )
- {
- m_os << indent() << (i.m_is_public ? "pub " : "") << i.m_name << ": " << i.m_type.print_pretty() << "\n";
- }
- dec_indent();
- m_os << indent() << "}\n";
- )
- )
- m_os << "\n";
-}
-
-void RustPrinter::handle_enum(const AST::Enum& s)
-{
- print_params(s.params());
- m_os << "\n";
- print_bounds(s.params());
-
- m_os << indent() << "{\n";
- inc_indent();
- unsigned int idx = 0;
- for( const auto& i : s.variants() )
- {
- m_os << indent() << "/*"<<idx<<"*/" << i.m_name;
- TU_MATCH(AST::EnumVariantData, (i.m_data), (e),
- (Value,
- m_os << " = " << e.m_value;
- ),
- (Tuple,
- m_os << "(";
- for( const auto& t : e.m_sub_types )
- m_os << t.print_pretty() << ", ";
- m_os << ")";
- ),
- (Struct,
- m_os << "{\n";
- inc_indent();
- for( const auto& i : e.m_fields )
- {
- m_os << indent() << i.m_name << ": " << i.m_type.print_pretty() << "\n";
- }
- dec_indent();
- m_os << indent() << "}";
- )
- )
- m_os << ",\n";
- idx ++;
- }
- dec_indent();
- m_os << indent() << "}\n";
- m_os << "\n";
-}
-
-void RustPrinter::handle_trait(const AST::Trait& s)
-{
- print_params(s.params());
- m_os << "\n";
- print_bounds(s.params());
-
- m_os << indent() << "{\n";
- inc_indent();
-
- for( const auto& i : s.items() )
- {
- TU_MATCH_DEF(AST::Item, (i.data), (e),
- (
- ),
- (Type,
- m_os << indent() << "type " << i.name << ";\n";
- ),
- (Function,
- handle_function(false, i.name, e);
- )
- )
- }
-
- dec_indent();
- m_os << indent() << "}\n";
- m_os << "\n";
-}
-
-void RustPrinter::handle_function(bool is_pub, const ::std::string& name, const AST::Function& f)
-{
- m_os << indent();
- m_os << (is_pub ? "pub " : "");
- // TODO: Unsafe
- // TODO: Const
- m_os << "fn " << name;
- print_params(f.params());
- m_os << "(";
- bool is_first = true;
- for( const auto& a : f.args() )
- {
- if( !is_first )
- m_os << ", ";
- print_pattern( a.first, false );
- m_os << ": " << a.second.print_pretty();
- is_first = false;
- }
- m_os << ")";
- if( !f.rettype().is_unit() )
- {
- m_os << " -> " << f.rettype().print_pretty();
- }
-
- if( f.code().is_valid() )
- {
- m_os << "\n";
- print_bounds(f.params());
-
- m_os << indent();
- f.code().visit_nodes(*this);
- m_os << "\n";
- //m_os << indent() << f.data.code() << "\n";
- }
- else
- {
- print_bounds(f.params());
- m_os << ";\n";
- }
-}
-
-void RustPrinter::inc_indent()
-{
- m_indent_level ++;
-}
-RepeatLitStr RustPrinter::indent()
-{
- return RepeatLitStr { " ", m_indent_level };
-}
-void RustPrinter::dec_indent()
-{
- m_indent_level --;
-}