summaryrefslogtreecommitdiff
path: root/src/dump_as_rust.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dump_as_rust.cpp')
-rw-r--r--src/dump_as_rust.cpp268
1 files changed, 263 insertions, 5 deletions
diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp
index 1a0b426d..ade350e8 100644
--- a/src/dump_as_rust.cpp
+++ b/src/dump_as_rust.cpp
@@ -26,7 +26,193 @@ public:
void handle_function(const AST::Item<AST::Function>& f);
+ virtual bool is_const() const override { return true; }
+ virtual void visit(AST::ExprNode_Block& n) override {
+ m_os << "{";
+ inc_indent();
+ 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();
+ if( !child.get() )
+ m_os << "/* nil */";
+ else
+ AST::NodeVisitor::visit(child);
+ }
+ m_os << "\n";
+ dec_indent();
+ m_os << indent() << "}";
+ }
+ virtual void visit(AST::ExprNode_Macro& n) override {
+ m_os << n.m_name << "!( /* TODO: Macro TT */ )";
+ }
+ virtual void visit(AST::ExprNode_Return& n) override {
+ m_os << "return ";
+ AST::NodeVisitor::visit(n.m_value);
+ }
+ virtual void visit(AST::ExprNode_LetBinding& n) override {
+ m_os << "let ";
+ print_pattern(n.m_pat);
+ m_os << " = ";
+ AST::NodeVisitor::visit(n.m_value);
+ }
+ virtual void visit(AST::ExprNode_Assign& n) override {
+ AST::NodeVisitor::visit(n.m_slot);
+ m_os << " = ";
+ AST::NodeVisitor::visit(n.m_value);
+ }
+ virtual void visit(AST::ExprNode_CallPath& n) override {
+ 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_os << "(";
+ AST::NodeVisitor::visit(n.m_val);
+ 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&) override {
+ throw ::std::runtime_error("unimplemented ExprNode_CallObject");
+ }
+ virtual void visit(AST::ExprNode_Match& n) override {
+ m_os << "match ";
+ AST::NodeVisitor::visit(n.m_val);
+ m_os << " {\n";
+ inc_indent();
+
+ for( auto& arm : n.m_arms )
+ {
+ m_os << indent();
+ print_pattern( arm.first );
+ m_os << " => ";
+ AST::NodeVisitor::visit(arm.second);
+ m_os << ",\n";
+ }
+
+ m_os << indent() << "}";
+ dec_indent();
+ }
+ virtual void visit(AST::ExprNode_If& n) override {
+ m_os << "if ";
+ AST::NodeVisitor::visit(n.m_cond);
+ m_os << " ";
+ AST::NodeVisitor::visit(n.m_true);
+ if(n.m_false.get())
+ {
+ m_os << " else ";
+ AST::NodeVisitor::visit(n.m_false);
+ }
+ }
+ virtual void visit(AST::ExprNode_Integer& n) override {
+ switch(n.m_datatype)
+ {
+ }
+ m_os << "0x" << ::std::hex << n.m_value << ::std::dec;
+ }
+ virtual void visit(AST::ExprNode_StructLiteral& n) override {
+ 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_Tuple& n) override {
+ 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_os << n.m_path;
+ }
+ virtual void visit(AST::ExprNode_Field& n) override {
+ m_os << "(";
+ AST::NodeVisitor::visit(n.m_obj);
+ m_os << ")." << n.m_name;
+ }
+ virtual void visit(AST::ExprNode_Deref&) override {
+ throw ::std::runtime_error("unimplemented ExprNode_Deref");
+ }
+ virtual void visit(AST::ExprNode_Cast& n) override {
+ AST::NodeVisitor::visit(n.m_value);
+ m_os << " as " << n.m_type;
+ }
+ virtual void visit(AST::ExprNode_BinOp& n) override {
+ #define IS(v, c) (dynamic_cast<c*>(&v) != 0)
+ if( IS(*n.m_left, AST::ExprNode_Cast) )
+ paren_wrap(n.m_left);
+ else if( IS(*n.m_left, AST::ExprNode_BinOp) )
+ paren_wrap(n.m_left);
+ else
+ AST::NodeVisitor::visit(n.m_left);
+ 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::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;
+ }
+ m_os << " ";
+ if( IS(*n.m_right, AST::ExprNode_BinOp) )
+ paren_wrap(n.m_right);
+ else
+ AST::NodeVisitor::visit(n.m_right);
+ }
+
+
private:
+ void paren_wrap(::std::unique_ptr<AST::ExprNode>& node) {
+ m_os << "(";
+ AST::NodeVisitor::visit(node);
+ m_os << ")";
+ }
+
void print_params(const AST::TypeParams& params);
void print_bounds(const AST::TypeParams& params);
void print_pattern(const AST::Pattern& p);
@@ -45,11 +231,32 @@ void Dump_Rust(const char *Filename, const AST::Crate& crate)
void RustPrinter::handle_module(const AST::Module& mod)
{
- m_os << "\n";
+ bool need_nl = true;
+
+ for( const auto& i : mod.imports() )
+ {
+ //if(need_nl) {
+ // m_os << "\n";
+ // need_nl = false;
+ //}
+ m_os << indent() << (i.is_pub ? "pub " : "") << "use " << i.data;
+ if( i.name == "" )
+ {
+ m_os << "::*";
+ }
+ else if( i.data.nodes().back().name() != i.name )
+ {
+ m_os << " as " << i.name;
+ }
+ m_os << ";\n";
+ }
+ need_nl = true;
for( const auto& sm : mod.submods() )
{
- m_os << indent() << (sm.second ? "pub " : "") << "mod " << sm.first.name() << " {\n";
+ m_os << "\n";
+ m_os << indent() << (sm.second ? "pub " : "") << "mod " << sm.first.name() << "\n";
+ m_os << indent() << "{\n";
inc_indent();
handle_module(sm.first);
dec_indent();
@@ -57,27 +264,47 @@ void RustPrinter::handle_module(const AST::Module& mod)
m_os << "\n";
}
+ for( const auto& i : mod.type_aliases() )
+ {
+ if(need_nl) {
+ m_os << "\n";
+ need_nl = false;
+ }
+ m_os << indent() << (i.is_pub ? "pub " : "") << "type " << i.name;
+ print_params(i.data.params());
+ m_os << " = " << i.data.type();
+ print_bounds(i.data.params());
+ m_os << ";\n";
+ }
+ need_nl = true;
for( const auto& i : mod.structs() )
{
+ m_os << "\n";
m_os << indent() << (i.is_pub ? "pub " : "") << "struct " << i.name;
handle_struct(i.data);
}
for( const auto& i : mod.enums() )
{
+ m_os << "\n";
m_os << indent() << (i.is_pub ? "pub " : "") << "enum " << i.name;
handle_enum(i.data);
}
for( const auto& i : mod.traits() )
{
+ m_os << "\n";
m_os << indent() << (i.is_pub ? "pub " : "") << "trait " << i.name;
handle_trait(i.data);
}
for( const auto& i : mod.statics() )
{
+ if(need_nl) {
+ m_os << "\n";
+ need_nl = false;
+ }
m_os << indent() << (i.is_pub ? "pub " : "");
switch( i.data.s_class() )
{
@@ -86,14 +313,41 @@ void RustPrinter::handle_module(const AST::Module& mod)
case AST::Static::MUT: m_os << "static mut "; break;
}
m_os << i.name << ": " << i.data.type() << " = ";
- //handle_expr(i.data.value());
+ i.data.value().visit_nodes(*this);
m_os << ";\n";
}
for( const auto& i : mod.functions() )
{
+ m_os << "\n";
handle_function(i);
}
+
+ for( const auto& i : mod.impls() )
+ {
+ m_os << "\n";
+ m_os << indent() << "impl";
+ print_params(i.params());
+ if( i.trait() != TypeRef() )
+ {
+ m_os << " " << i.trait() << " for";
+ }
+ m_os << " " << i.type() << "\n";
+
+ print_bounds(i.params());
+ m_os << indent() << "{\n";
+ inc_indent();
+ for( const auto& t : i.types() )
+ {
+ m_os << indent() << "type " << t.name << " = " << t.data << ";\n";
+ }
+ for( const auto& t : i.functions() )
+ {
+ handle_function(t);
+ }
+ dec_indent();
+ m_os << indent() << "}\n";
+ }
}
void RustPrinter::print_params(const AST::TypeParams& params)
@@ -230,7 +484,7 @@ void RustPrinter::handle_trait(const AST::Trait& s)
for( const auto& i : s.types() )
{
- m_os << indent() << "type " << i.name << "\n";
+ m_os << indent() << "type " << i.name << ";\n";
}
for( const auto& i : s.functions() )
{
@@ -244,6 +498,7 @@ void RustPrinter::handle_trait(const AST::Trait& s)
void RustPrinter::handle_function(const AST::Item<AST::Function>& f)
{
+ m_os << "\n";
m_os << indent() << (f.is_pub ? "pub " : "") << "fn " << f.name;
print_params(f.data.params());
m_os << "(";
@@ -267,7 +522,10 @@ void RustPrinter::handle_function(const AST::Item<AST::Function>& f)
m_os << "\n";
print_bounds(f.data.params());
- m_os << indent() << f.data.code() << "\n";
+ m_os << indent();
+ f.data.code().visit_nodes(*this);
+ m_os << "\n";
+ //m_os << indent() << f.data.code() << "\n";
}
else
{