// <http://www.gnu.org/licenses/>.
#include "rust-desugar-for-loops.h"
-#include "rust-ast-visitor.h"
#include "rust-ast.h"
#include "rust-hir-map.h"
#include "rust-path.h"
DesugarForLoops::DesugarForLoops () {}
-void
-DesugarForLoops::go (AST::Crate &crate)
-{
- DefaultASTVisitor::visit (crate);
-}
-
-static void
-replace_for_loop (std::unique_ptr<Expr> &for_loop,
- std::unique_ptr<Expr> &&expanded)
-{
- for_loop = std::move (expanded);
-}
-
MatchArm
DesugarForLoops::DesugarCtx::make_match_arm (std::unique_ptr<Pattern> &&path)
{
}
std::unique_ptr<Expr>
-DesugarForLoops::desugar (AST::ForLoopExpr &expr)
+DesugarForLoops::desugar (ForLoopExpr &expr)
{
auto ctx = DesugarCtx (expr.get_locus ());
}
void
-DesugarForLoops::maybe_desugar_expr (std::unique_ptr<Expr> &expr)
+DesugarForLoops::go (std::unique_ptr<Expr> &ptr)
{
- if (expr->get_expr_kind () == AST::Expr::Kind::Loop)
- {
- auto &loop = static_cast<AST::BaseLoopExpr &> (*expr);
-
- if (loop.get_loop_kind () == AST::BaseLoopExpr::Kind::For)
- {
- auto &for_loop = static_cast<AST::ForLoopExpr &> (loop);
-
- auto desugared = desugar (for_loop);
+ rust_assert (ptr->get_expr_kind () == Expr::Kind::Loop);
- replace_for_loop (expr, std::move (desugared));
- }
- }
-}
+ auto &loop = static_cast<BaseLoopExpr &> (*ptr);
-void
-DesugarForLoops::visit (AST::BlockExpr &block)
-{
- for (auto &stmt : block.get_statements ())
- if (stmt->get_stmt_kind () == AST::Stmt::Kind::Expr)
- maybe_desugar_expr (static_cast<AST::ExprStmt &> (*stmt).get_expr_ptr ());
+ rust_assert (loop.get_loop_kind () == BaseLoopExpr::Kind::For);
- if (block.has_tail_expr ())
- maybe_desugar_expr (block.get_tail_expr_ptr ());
+ auto &for_loop = static_cast<ForLoopExpr &> (loop);
+ auto desugared = DesugarForLoops ().desugar (for_loop);
- DefaultASTVisitor::visit (block);
+ ptr = std::move (desugared);
}
} // namespace AST
#define RUST_DESUGAR_FOR_LOOPS_H
#include "rust-ast-builder.h"
-#include "rust-ast-visitor.h"
#include "rust-expr.h"
namespace Rust {
// of the way the typechecker is currently structured, where it will fetch name
// resolution information in order to typecheck paths - which technically isn't
// necessary.
-class DesugarForLoops : public DefaultASTVisitor
+class DesugarForLoops
{
- using DefaultASTVisitor::visit;
-
public:
- DesugarForLoops ();
- void go (AST::Crate &);
+ static void go (std::unique_ptr<Expr> &ptr);
private:
+ DesugarForLoops ();
+
struct DesugarCtx
{
DesugarCtx (location_t loc) : builder (Builder (loc)), loc (loc) {}
constexpr static const char *result_id = "#result";
};
- std::unique_ptr<Expr> desugar (AST::ForLoopExpr &expr);
- void maybe_desugar_expr (std::unique_ptr<Expr> &expr);
-
- void visit (AST::BlockExpr &) override;
+ std::unique_ptr<Expr> desugar (ForLoopExpr &expr);
};
} // namespace AST
#include "rust-ast-visitor.h"
#include "rust-desugar-question-mark.h"
#include "rust-desugar-try-block.h"
+#include "rust-desugar-for-loops.h"
#include "rust-ast-full.h"
+#include "rust-expr.h"
+#include "rust-stmt.h"
namespace Rust {
namespace AST {
DefaultASTVisitor::visit (crate);
}
+void
+ExpressionYeast::dispatch_loops (std::unique_ptr<Expr> &loop_expr)
+{
+ auto &loop = static_cast<BaseLoopExpr &> (*loop_expr.get ());
+
+ switch (loop.get_loop_kind ())
+ {
+ case BaseLoopExpr::Kind::For:
+ DesugarForLoops::go (loop_expr);
+ break;
+ case BaseLoopExpr::Kind::Loop:
+ case BaseLoopExpr::Kind::While:
+ case BaseLoopExpr::Kind::WhileLet:
+ break;
+ }
+}
+
void
ExpressionYeast::dispatch (std::unique_ptr<Expr> &expr)
{
switch (expr->get_expr_kind ())
{
- // TODO: Handle try-blocks
case Expr::Kind::ErrorPropagation:
DesugarQuestionMark::go (expr);
break;
case Expr::Kind::Try:
DesugarTryBlock::go (expr);
break;
+ case Expr::Kind::Loop:
+ dispatch_loops (expr);
+ break;
default:
break;
ExpressionYeast::visit (BlockExpr &block)
{
for (auto &stmt : block.get_statements ())
- DefaultASTVisitor::visit (stmt);
+ if (stmt->get_stmt_kind () == Stmt::Kind::Expr)
+ dispatch (static_cast<ExprStmt &> (*stmt).get_expr_ptr ());
if (block.has_tail_expr ())
dispatch (block.get_tail_expr_ptr ());
+
+ DefaultASTVisitor::visit (block);
}
void
private:
// Dispatch to the proper desugar
void dispatch (std::unique_ptr<Expr> &expr);
+ void dispatch_loops (std::unique_ptr<Expr> &loop_expr);
void visit (AST::ExprStmt &) override;
void visit (AST::CallExpr &) override;
{
AST::ExpressionYeast ().go (crate);
- AST::DesugarForLoops ().go (crate);
AST::DesugarApit ().go (crate);
// HACK: we may need a final TopLevel pass