// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use build::{BlockAnd, BlockAndExtension, Builder};
use hair::*;
use rustc::mir::repr::*;

impl<'a,'tcx> Builder<'a,'tcx> {
    pub fn stmts(&mut self, mut block: BasicBlock, stmts: Vec<StmtRef<'tcx>>) -> BlockAnd<()> {
        // This convoluted structure is to avoid using recursion as we walk down a list
        // of statements. Basically, the structure we get back is something like:
        //
        //    let x = <init> in {
        //       let y = <init> in {
        //           expr1;
        //           expr2;
        //       }
        //    }
        //
        // To process this, we keep a stack of (Option<CodeExtent>,
        // vec::IntoIter<Stmt>) pairs.  At each point we pull off the
        // top most pair and extract one statement from the
        // iterator. Once it's complete, we pop the scope from the
        // first half the pair.
        let this = self;
        let mut stmt_lists = vec![(None, stmts.into_iter())];
        while !stmt_lists.is_empty() {
            let stmt = {
                let &mut (_, ref mut stmts) = stmt_lists.last_mut().unwrap();
                stmts.next()
            };

            let stmt = match stmt {
                Some(stmt) => stmt,
                None => {
                    let (extent, _) = stmt_lists.pop().unwrap();
                    if let Some(extent) = extent {
                        this.pop_scope(extent, block);
                    }
                    continue
                }
            };

            let Stmt { span, kind } = this.hir.mirror(stmt);
            match kind {
                StmtKind::Let { remainder_scope, init_scope, pattern, initializer, stmts } => {
                    this.push_scope(remainder_scope, block);
                    stmt_lists.push((Some(remainder_scope), stmts.into_iter()));
                    unpack!(block = this.in_scope(init_scope, block, move |this| {
                        // FIXME #30046                              ^~~~
                        match initializer {
                            Some(initializer) => {
                                this.expr_into_pattern(block, remainder_scope, pattern, initializer)
                            }
                            None => {
                                this.declare_bindings(remainder_scope, &pattern);
                                block.unit()
                            }
                        }
                    }));
                }

                StmtKind::Expr { scope, expr } => {
                    unpack!(block = this.in_scope(scope, block, |this| {
                        let expr = this.hir.mirror(expr);
                        let temp = this.temp(expr.ty.clone());
                        unpack!(block = this.into(&temp, block, expr));
                        this.cfg.push_drop(block, span, DropKind::Deep, &temp);
                        block.unit()
                    }));
                }
            }
        }
        block.unit()
    }
}
