diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/path.cpp | 3 | ||||
-rw-r--r-- | src/dump_as_rust.cpp | 78 | ||||
-rw-r--r-- | src/parse/expr.cpp | 14 |
3 files changed, 82 insertions, 13 deletions
diff --git a/src/ast/path.cpp b/src/ast/path.cpp index f3fc5e82..103ca1b2 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -356,7 +356,8 @@ void Path::print_pretty(::std::ostream& os) const } break; case Path::ABSOLUTE: - os << "{"<<path.m_crate<<"}"; + if( path.m_crate != "" ) + os << "::\""<<path.m_crate<<"\""; for(const auto& n : path.m_nodes) { #if PRETTY_PATH_PRINT diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp index ade350e8..83c7f160 100644 --- a/src/dump_as_rust.cpp +++ b/src/dump_as_rust.cpp @@ -8,15 +8,19 @@ #include "ast/expr.hpp" #include <main_bindings.hpp> +#define IS(v, c) (dynamic_cast<c*>(&v) != 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_indent_level(0), + m_expr_root(false) {} void handle_module(const AST::Module& mod); @@ -40,6 +44,7 @@ public: } m_os << "\n"; m_os << indent(); + m_expr_root = true; if( !child.get() ) m_os << "/* nil */"; else @@ -50,24 +55,29 @@ public: 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_Return& n) override { + m_expr_root = false; m_os << "return "; 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); 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); m_os << " = "; 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; @@ -83,6 +93,7 @@ public: m_os << ")"; } virtual void visit(AST::ExprNode_CallMethod& n) override { + m_expr_root = false; m_os << "("; AST::NodeVisitor::visit(n.m_val); m_os << ")." << n.m_method; @@ -100,13 +111,25 @@ public: m_os << ")"; } virtual void visit(AST::ExprNode_CallObject&) override { + m_expr_root = false; throw ::std::runtime_error("unimplemented ExprNode_CallObject"); } 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); - m_os << " {\n"; - inc_indent(); + + if(expr_root) + { + m_os << "\n"; + m_os << indent() << "{\n"; + } + else + { + m_os << " {\n"; + inc_indent(); + } for( auto& arm : n.m_arms ) { @@ -117,27 +140,61 @@ public: m_os << ",\n"; } - m_os << indent() << "}"; - dec_indent(); + 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); - m_os << " "; + if( expr_root ) + { + m_os << "\n"; + m_os << indent(); + } + else + { + m_os << " "; + } AST::NodeVisitor::visit(n.m_true); if(n.m_false.get()) { - m_os << " else "; + if( expr_root ) + { + m_os << "\n"; + m_os << indent() << "else"; + // handle chained if statements nicely + if( IS(*n.m_false, AST::ExprNode_If) ) { + m_expr_root = true; + m_os << " "; + } + else + m_os << "\n" << indent(); + } + else + { + m_os << " else "; + } AST::NodeVisitor::visit(n.m_false); } } virtual void visit(AST::ExprNode_Integer& n) override { + m_expr_root = false; switch(n.m_datatype) { } m_os << "0x" << ::std::hex << n.m_value << ::std::dec; } 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 ) @@ -156,6 +213,7 @@ public: dec_indent(); } virtual void visit(AST::ExprNode_Tuple& n) override { + m_expr_root = false; m_os << "("; for( auto& item : n.m_values ) { @@ -165,22 +223,26 @@ public: 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; m_os << "("; AST::NodeVisitor::visit(n.m_obj); m_os << ")." << n.m_name; } virtual void visit(AST::ExprNode_Deref&) override { + m_expr_root = false; throw ::std::runtime_error("unimplemented ExprNode_Deref"); } 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 { - #define IS(v, c) (dynamic_cast<c*>(&v) != 0) + m_expr_root = false; if( IS(*n.m_left, AST::ExprNode_Cast) ) paren_wrap(n.m_left); else if( IS(*n.m_left, AST::ExprNode_BinOp) ) diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 91cedabd..2ed992ce 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -178,23 +178,29 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex) ::std::vector<ExprNodeP> nodes;
GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN);
+
while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
{
lex.putback(tok);
bool opt_semicolon = false;
// NOTE: This semicolon handling is SHIT.
nodes.push_back(Parse_Stmt(lex, opt_semicolon));
- if( GET_TOK(tok, lex) != TOK_BRACE_CLOSE ) {
+ if( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
+ {
if( !opt_semicolon )
+ {
CHECK_TOK(tok, TOK_SEMICOLON);
+ }
else
lex.putback(tok);
}
- else {
- nodes.push_back(nullptr);
- break;
+ else
+ {
+ goto pass_value;
}
}
+ nodes.push_back(nullptr);
+pass_value:
return NEWNODE( AST::ExprNode_Block, ::std::move(nodes) );
}
|