<commit_before>//! Track which values are live in an EBB with instruction granularity.
//!
//! The `LiveValueTracker` keeps track of the set of live SSA values at each instruction in an EBB.
//! The sets of live values are computed on the fly as the tracker is moved from instruction to
//! instruction, starting at the EBB header.

use dominator_tree::DominatorTree;
use entity::{EntityList, ListPool};
use ir::instructions::BranchInfo;
use ir::{Inst, Ebb, Value, DataFlowGraph, Layout, ExpandedProgramPoint};
use partition_slice::partition_slice;
use regalloc::affinity::Affinity;
use regalloc::liveness::Liveness;
use regalloc::liverange::LiveRange;
use std::collections::HashMap;
use std::vec::Vec;

type ValueList = EntityList<Value>;

/// Compute and track live values throughout an EBB.
pub struct LiveValueTracker {
    /// The set of values that are live at the current program point.
    live: LiveValueVec,

    /// Saved set of live values for every jump and branch that can potentially be an immediate
    /// dominator of an EBB.
    ///
    /// This is the set of values that are live *before* the branch.
    idom_sets: HashMap<Inst, ValueList>,

    /// Memory pool for the live sets.
    idom_pool: ListPool<Value>,
}

/// Information about a value that is live at the current program point.
pub struct LiveValue {
    /// The live value.
    pub value: Value,

    /// The local ending point of the live range in the current EBB, as returned by
    /// `LiveRange::def_local_end()` or `LiveRange::livein_local_end()`.
    pub endpoint: Inst,

    /// The affinity of the value as represented in its `LiveRange`.
    ///
    /// This value is simply a copy of the affinity stored in the live range. We copy it because
    /// almost all users of `LiveValue` need to look at it.
    pub affinity: Affinity,

    /// The live range for this value never leaves its EBB.
    pub is_local: bool,

    /// This value is dead - the live range ends immediately.
    pub is_dead: bool,
}

struct LiveValueVec {
    /// The set of values that are live at the current program point.
    values: Vec<LiveValue>,

    /// How many values at the front of `values` are known to be live after `inst`?
    ///
    /// This is used to pass a much smaller slice to `partition_slice` when its called a second
    /// time for the same instruction.
    live_prefix: Option<(Inst, usize)>,
}

impl LiveValueVec {
    fn new() -> Self {
        Self {
            values: Vec::new(),
            live_prefix: None,
        }
    }

    /// Add a new live value to `values`. Copy some properties from `lr`.
    fn push(&mut self, value: Value, endpoint: Inst, lr: &LiveRange) {
        self.values.push(LiveValue {
            value,
            endpoint,
            affinity: lr.affinity,
            is_local: lr.is_local(),
            is_dead: lr.is_dead(),
        });
    }

    /// Remove all elements.
    fn clear(&mut self) {
        self.values.clear();
        self.live_prefix = None;
    }

    /// Make sure that the values killed by `next_inst` are moved to the end of the `values`
    /// vector.
    ///
    /// Returns the number of values that will be live after `next_inst`.
    fn live_after(&mut self, next_inst: Inst) -> usize {
        // How many values at the front of the vector are already known to survive `next_inst`?
        // We don't need to pass this prefix to `partition_slice()`
        let keep = match self.live_prefix {
            Some((i, prefix)) if i == next_inst => prefix,
            _ => 0,
        };

        // Move the remaining surviving values to the front partition of the vector.
        let prefix = keep + partition_slice(&mut self.values[keep..], |v| v.endpoint != next_inst);

        // Remember the new prefix length in case we get called again for the same `next_inst`.
        self.live_prefix = Some((next_inst, prefix));
        prefix
    }

    /// Remove the values killed by `next_inst`.
    fn remove_kill_values(&mut self, next_inst: Inst) {
        let keep = self.live_after(next_inst);
        self.values.truncate(keep);
    }

    /// Remove any dead values.
    fn remove_dead_values(&mut self) {
        self.values.retain(|v| !v.is_dead);
        self.live_prefix = None;
    }
}

impl LiveValueTracker {
    /// Create a new blank tracker.
    pub fn new() -> Self {
        Self {
            live: LiveValueVec::new(),
            idom_sets: HashMap::new(),
            idom_pool: ListPool::new(),
        }
    }

    /// Clear all cached information.
    pub fn clear(&mut self) {
        self.live.clear();
        self.idom_sets.clear();
        self.idom_pool.clear();
    }

    /// Get the set of currently live values.
    ///
    /// Between calls to `process_inst()` and `drop_dead()`, this includes both values killed and
    /// defined by the current instruction.
    pub fn live(&self) -> &[LiveValue] {
        &self.live.values
    }

    /// Get a mutable set of currently live values.
    ///
    /// Use with care and don't move entries around.
    pub fn live_mut(&mut self) -> &mut [LiveValue] {
        &mut self.live.values
    }

    /// Move the current position to the top of `ebb`.
    ///
    /// This depends on the stored live value set at `ebb`'s immediate dominator, so that must have
    /// been visited first.
    ///
    /// Returns `(liveins, args)` as a pair of slices. The first slice is the set of live-in values
    /// from the immediate dominator. The second slice is the set of `ebb` parameters.
    ///
    /// Dead parameters with no uses are included in `args`. Call `drop_dead_args()` to remove them.
    pub fn ebb_top(
        &mut self,
        ebb: Ebb,
        dfg: &DataFlowGraph,
        liveness: &Liveness,
        layout: &Layout,
        domtree: &DominatorTree,
    ) -> (&[LiveValue], &[LiveValue]) {
        // Start over, compute the set of live values at the top of the EBB from two sources:
        //
        // 1. Values that were live before `ebb`'s immediate dominator, filtered for those that are
        //    actually live-in.
        // 2. Arguments to `ebb` that are not dead.
        //
        self.live.clear();

        // Compute the live-in values. Start by filtering the set of values that were live before
        // the immediate dominator. Just use the empty set if there's no immediate dominator (i.e.,
        // the entry block or an unreachable block).
        if let Some(idom) = domtree.idom(ebb) {
            // If the immediate dominator exits, we must have a stored list for it. This is a
            // requirement to the order EBBs are visited: All dominators must have been processed
            // before the current EBB.
            let idom_live_list = self.idom_sets.get(&idom).expect(
                "No stored live set for dominator",
            );
            let ctx = liveness.context(layout);
            // Get just the values that are live-in to `ebb`.
            for &value in idom_live_list.as_slice(&self.idom_pool) {
                let lr = liveness.get(value).expect(
                    "Immediate dominator value has no live range",
                );

                // Check if this value is live-in here.
                if let Some(endpoint) = lr.livein_local_end(ebb, ctx) {
                    self.live.push(value, endpoint, lr);
                }
            }
        }

        // Now add all the live parameters to `ebb`.
        let first_arg = self.live.values.len();
        for &value in dfg.ebb_params(ebb) {
            let lr = &liveness[value];
            debug_assert_eq!(lr.def(), ebb.into());
            match lr.def_local_end().into() {
                ExpandedProgramPoint::Inst(endpoint) => {
                    self.live.push(value, endpoint, lr);
                }
                ExpandedProgramPoint::Ebb(local_ebb) => {
                    // This is a dead EBB parameter which is not even live into the first
                    // instruction in the EBB.
                    debug_assert_eq!(
                        local_ebb,
                        ebb,
                        "EBB parameter live range ends at wrong EBB header"
                    );
                    // Give this value a fake endpoint that is the first instruction in the EBB.
                    // We expect it to be removed by calling `drop_dead_args()`.
                    self.live.push(
                        value,
                        layout.first_inst(ebb).expect("Empty EBB"),
                        lr,
                    );
                }
            }
        }

        self.live.values.split_at(first_arg)
    }

    /// Prepare to move past `inst`.
    ///
    /// Determine the set of already live values that are killed by `inst`, and add the new defined
    /// values to the tracked set.
    ///
    /// Returns `(throughs, kills, defs)` as a tuple of slices:
    ///
    /// 1. The `throughs` slice is the set of live-through values that are neither defined nor
    ///    killed by the instruction.
    /// 2. The `kills` slice is the set of values that were live before the instruction and are
    ///    killed at the instruction. This does not include dead defs.
    /// 3. The `defs` slice is guaranteed to be in the same order as `inst`'s results, and includes
    ///    dead defines.
    ///
    /// The order of `throughs` and `kills` is arbitrary.
    ///
    /// The `drop_dead()` method must be called next to actually remove the dead values from the
    /// tracked set after the two returned slices are no longer needed.
    pub fn process_inst(
        &mut self,
        inst: Inst,
        dfg: &DataFlowGraph,
        liveness: &Liveness,
    ) -> (&[LiveValue], &[LiveValue], &[LiveValue]) {
        // Save a copy of the live values before any branches or jumps that could be somebody's
        // immediate dominator.
        match dfg.analyze_branch(inst) {
            BranchInfo::NotABranch => {}
            _ => self.save_idom_live_set(inst),
        }

        // Move killed values to the end of the vector.
        // Don't remove them yet, `drop_dead()` will do that.
        let first_kill = self.live.live_after(inst);

        // Add the values defined by `inst`.
        let first_def = self.live.values.len();
        for &value in dfg.inst_results(inst) {
            let lr = &liveness[value];
            debug_assert_eq!(lr.def(), inst.into());
            match lr.def_local_end().into() {
                ExpandedProgramPoint::Inst(endpoint) => {
                    self.live.push(value, endpoint, lr);
                }
                ExpandedProgramPoint::Ebb(ebb) => {
                    panic!("Instruction result live range can't end at {}", ebb);
                }
            }
        }

        (
            &self.live.values[0..first_kill],
            &self.live.values[first_kill..first_def],
            &self.live.values[first_def..],
        )
    }

    /// Prepare to move past a ghost instruction.
    ///
    /// This is like `process_inst`, except any defs are ignored.
    ///
    /// Returns `(throughs, kills)`.
    pub fn process_ghost(&mut self, inst: Inst) -> (&[LiveValue], &[LiveValue]) {
        let first_kill = self.live.live_after(inst);
        self.live.values.as_slice().split_at(first_kill)
    }

    /// Drop the values that are now dead after moving past `inst`.
    ///
    /// This removes both live values that were killed by `inst` and dead defines on `inst` itself.
    ///
    /// This must be called after `process_inst(inst)` and before proceeding to the next
    /// instruction.
    pub fn drop_dead(&mut self, inst: Inst) {
        // Remove both live values that were killed by `inst` and dead defines from `inst`.
        self.live.remove_kill_values(inst);
    }

    /// Drop any values that are marked as `is_dead`.
    ///
    /// Use this after calling `ebb_top` to clean out dead EBB parameters.
    pub fn drop_dead_params(&mut self) {
        self.live.remove_dead_values();
    }

    /// Process new spills.
    ///
    /// Any values where `f` returns true are spilled and will be treated as if their affinity was
    /// `Stack`.
    pub fn process_spills<F>(&mut self, mut f: F)
    where
        F: FnMut(Value) -> bool,
    {
        for lv in &mut self.live.values {
            if f(lv.value) {
                lv.affinity = Affinity::Stack;
            }
        }
    }

    /// Save the current set of live values so it is associated with `idom`.
    fn save_idom_live_set(&mut self, idom: Inst) {
        let values = self.live.values.iter().map(|lv| lv.value);
        let pool = &mut self.idom_pool;
        // If there already is a set saved for `idom`, just keep it.
        self.idom_sets.entry(idom).or_insert_with(|| {
            let mut list = ValueList::default();
            list.extend(values, pool);
            list
        });
    }
}
<commit_msg>Avoid calling `analyze_branch()` when the `BranchInfo` is not needed.<commit_after>//! Track which values are live in an EBB with instruction granularity.
//!
//! The `LiveValueTracker` keeps track of the set of live SSA values at each instruction in an EBB.
//! The sets of live values are computed on the fly as the tracker is moved from instruction to
//! instruction, starting at the EBB header.

use dominator_tree::DominatorTree;
use entity::{EntityList, ListPool};
use ir::{Inst, Ebb, Value, DataFlowGraph, Layout, ExpandedProgramPoint};
use partition_slice::partition_slice;
use regalloc::affinity::Affinity;
use regalloc::liveness::Liveness;
use regalloc::liverange::LiveRange;
use std::collections::HashMap;
use std::vec::Vec;

type ValueList = EntityList<Value>;

/// Compute and track live values throughout an EBB.
pub struct LiveValueTracker {
    /// The set of values that are live at the current program point.
    live: LiveValueVec,

    /// Saved set of live values for every jump and branch that can potentially be an immediate
    /// dominator of an EBB.
    ///
    /// This is the set of values that are live *before* the branch.
    idom_sets: HashMap<Inst, ValueList>,

    /// Memory pool for the live sets.
    idom_pool: ListPool<Value>,
}

/// Information about a value that is live at the current program point.
pub struct LiveValue {
    /// The live value.
    pub value: Value,

    /// The local ending point of the live range in the current EBB, as returned by
    /// `LiveRange::def_local_end()` or `LiveRange::livein_local_end()`.
    pub endpoint: Inst,

    /// The affinity of the value as represented in its `LiveRange`.
    ///
    /// This value is simply a copy of the affinity stored in the live range. We copy it because
    /// almost all users of `LiveValue` need to look at it.
    pub affinity: Affinity,

    /// The live range for this value never leaves its EBB.
    pub is_local: bool,

    /// This value is dead - the live range ends immediately.
    pub is_dead: bool,
}

struct LiveValueVec {
    /// The set of values that are live at the current program point.
    values: Vec<LiveValue>,

    /// How many values at the front of `values` are known to be live after `inst`?
    ///
    /// This is used to pass a much smaller slice to `partition_slice` when its called a second
    /// time for the same instruction.
    live_prefix: Option<(Inst, usize)>,
}

impl LiveValueVec {
    fn new() -> Self {
        Self {
            values: Vec::new(),
            live_prefix: None,
        }
    }

    /// Add a new live value to `values`. Copy some properties from `lr`.
    fn push(&mut self, value: Value, endpoint: Inst, lr: &LiveRange) {
        self.values.push(LiveValue {
            value,
            endpoint,
            affinity: lr.affinity,
            is_local: lr.is_local(),
            is_dead: lr.is_dead(),
        });
    }

    /// Remove all elements.
    fn clear(&mut self) {
        self.values.clear();
        self.live_prefix = None;
    }

    /// Make sure that the values killed by `next_inst` are moved to the end of the `values`
    /// vector.
    ///
    /// Returns the number of values that will be live after `next_inst`.
    fn live_after(&mut self, next_inst: Inst) -> usize {
        // How many values at the front of the vector are already known to survive `next_inst`?
        // We don't need to pass this prefix to `partition_slice()`
        let keep = match self.live_prefix {
            Some((i, prefix)) if i == next_inst => prefix,
            _ => 0,
        };

        // Move the remaining surviving values to the front partition of the vector.
        let prefix = keep + partition_slice(&mut self.values[keep..], |v| v.endpoint != next_inst);

        // Remember the new prefix length in case we get called again for the same `next_inst`.
        self.live_prefix = Some((next_inst, prefix));
        prefix
    }

    /// Remove the values killed by `next_inst`.
    fn remove_kill_values(&mut self, next_inst: Inst) {
        let keep = self.live_after(next_inst);
        self.values.truncate(keep);
    }

    /// Remove any dead values.
    fn remove_dead_values(&mut self) {
        self.values.retain(|v| !v.is_dead);
        self.live_prefix = None;
    }
}

impl LiveValueTracker {
    /// Create a new blank tracker.
    pub fn new() -> Self {
        Self {
            live: LiveValueVec::new(),
            idom_sets: HashMap::new(),
            idom_pool: ListPool::new(),
        }
    }

    /// Clear all cached information.
    pub fn clear(&mut self) {
        self.live.clear();
        self.idom_sets.clear();
        self.idom_pool.clear();
    }

    /// Get the set of currently live values.
    ///
    /// Between calls to `process_inst()` and `drop_dead()`, this includes both values killed and
    /// defined by the current instruction.
    pub fn live(&self) -> &[LiveValue] {
        &self.live.values
    }

    /// Get a mutable set of currently live values.
    ///
    /// Use with care and don't move entries around.
    pub fn live_mut(&mut self) -> &mut [LiveValue] {
        &mut self.live.values
    }

    /// Move the current position to the top of `ebb`.
    ///
    /// This depends on the stored live value set at `ebb`'s immediate dominator, so that must have
    /// been visited first.
    ///
    /// Returns `(liveins, args)` as a pair of slices. The first slice is the set of live-in values
    /// from the immediate dominator. The second slice is the set of `ebb` parameters.
    ///
    /// Dead parameters with no uses are included in `args`. Call `drop_dead_args()` to remove them.
    pub fn ebb_top(
        &mut self,
        ebb: Ebb,
        dfg: &DataFlowGraph,
        liveness: &Liveness,
        layout: &Layout,
        domtree: &DominatorTree,
    ) -> (&[LiveValue], &[LiveValue]) {
        // Start over, compute the set of live values at the top of the EBB from two sources:
        //
        // 1. Values that were live before `ebb`'s immediate dominator, filtered for those that are
        //    actually live-in.
        // 2. Arguments to `ebb` that are not dead.
        //
        self.live.clear();

        // Compute the live-in values. Start by filtering the set of values that were live before
        // the immediate dominator. Just use the empty set if there's no immediate dominator (i.e.,
        // the entry block or an unreachable block).
        if let Some(idom) = domtree.idom(ebb) {
            // If the immediate dominator exits, we must have a stored list for it. This is a
            // requirement to the order EBBs are visited: All dominators must have been processed
            // before the current EBB.
            let idom_live_list = self.idom_sets.get(&idom).expect(
                "No stored live set for dominator",
            );
            let ctx = liveness.context(layout);
            // Get just the values that are live-in to `ebb`.
            for &value in idom_live_list.as_slice(&self.idom_pool) {
                let lr = liveness.get(value).expect(
                    "Immediate dominator value has no live range",
                );

                // Check if this value is live-in here.
                if let Some(endpoint) = lr.livein_local_end(ebb, ctx) {
                    self.live.push(value, endpoint, lr);
                }
            }
        }

        // Now add all the live parameters to `ebb`.
        let first_arg = self.live.values.len();
        for &value in dfg.ebb_params(ebb) {
            let lr = &liveness[value];
            debug_assert_eq!(lr.def(), ebb.into());
            match lr.def_local_end().into() {
                ExpandedProgramPoint::Inst(endpoint) => {
                    self.live.push(value, endpoint, lr);
                }
                ExpandedProgramPoint::Ebb(local_ebb) => {
                    // This is a dead EBB parameter which is not even live into the first
                    // instruction in the EBB.
                    debug_assert_eq!(
                        local_ebb,
                        ebb,
                        "EBB parameter live range ends at wrong EBB header"
                    );
                    // Give this value a fake endpoint that is the first instruction in the EBB.
                    // We expect it to be removed by calling `drop_dead_args()`.
                    self.live.push(
                        value,
                        layout.first_inst(ebb).expect("Empty EBB"),
                        lr,
                    );
                }
            }
        }

        self.live.values.split_at(first_arg)
    }

    /// Prepare to move past `inst`.
    ///
    /// Determine the set of already live values that are killed by `inst`, and add the new defined
    /// values to the tracked set.
    ///
    /// Returns `(throughs, kills, defs)` as a tuple of slices:
    ///
    /// 1. The `throughs` slice is the set of live-through values that are neither defined nor
    ///    killed by the instruction.
    /// 2. The `kills` slice is the set of values that were live before the instruction and are
    ///    killed at the instruction. This does not include dead defs.
    /// 3. The `defs` slice is guaranteed to be in the same order as `inst`'s results, and includes
    ///    dead defines.
    ///
    /// The order of `throughs` and `kills` is arbitrary.
    ///
    /// The `drop_dead()` method must be called next to actually remove the dead values from the
    /// tracked set after the two returned slices are no longer needed.
    pub fn process_inst(
        &mut self,
        inst: Inst,
        dfg: &DataFlowGraph,
        liveness: &Liveness,
    ) -> (&[LiveValue], &[LiveValue], &[LiveValue]) {
        // Save a copy of the live values before any branches or jumps that could be somebody's
        // immediate dominator.
        if dfg[inst].opcode().is_branch() {
            self.save_idom_live_set(inst);
        }

        // Move killed values to the end of the vector.
        // Don't remove them yet, `drop_dead()` will do that.
        let first_kill = self.live.live_after(inst);

        // Add the values defined by `inst`.
        let first_def = self.live.values.len();
        for &value in dfg.inst_results(inst) {
            let lr = &liveness[value];
            debug_assert_eq!(lr.def(), inst.into());
            match lr.def_local_end().into() {
                ExpandedProgramPoint::Inst(endpoint) => {
                    self.live.push(value, endpoint, lr);
                }
                ExpandedProgramPoint::Ebb(ebb) => {
                    panic!("Instruction result live range can't end at {}", ebb);
                }
            }
        }

        (
            &self.live.values[0..first_kill],
            &self.live.values[first_kill..first_def],
            &self.live.values[first_def..],
        )
    }

    /// Prepare to move past a ghost instruction.
    ///
    /// This is like `process_inst`, except any defs are ignored.
    ///
    /// Returns `(throughs, kills)`.
    pub fn process_ghost(&mut self, inst: Inst) -> (&[LiveValue], &[LiveValue]) {
        let first_kill = self.live.live_after(inst);
        self.live.values.as_slice().split_at(first_kill)
    }

    /// Drop the values that are now dead after moving past `inst`.
    ///
    /// This removes both live values that were killed by `inst` and dead defines on `inst` itself.
    ///
    /// This must be called after `process_inst(inst)` and before proceeding to the next
    /// instruction.
    pub fn drop_dead(&mut self, inst: Inst) {
        // Remove both live values that were killed by `inst` and dead defines from `inst`.
        self.live.remove_kill_values(inst);
    }

    /// Drop any values that are marked as `is_dead`.
    ///
    /// Use this after calling `ebb_top` to clean out dead EBB parameters.
    pub fn drop_dead_params(&mut self) {
        self.live.remove_dead_values();
    }

    /// Process new spills.
    ///
    /// Any values where `f` returns true are spilled and will be treated as if their affinity was
    /// `Stack`.
    pub fn process_spills<F>(&mut self, mut f: F)
    where
        F: FnMut(Value) -> bool,
    {
        for lv in &mut self.live.values {
            if f(lv.value) {
                lv.affinity = Affinity::Stack;
            }
        }
    }

    /// Save the current set of live values so it is associated with `idom`.
    fn save_idom_live_set(&mut self, idom: Inst) {
        let values = self.live.values.iter().map(|lv| lv.value);
        let pool = &mut self.idom_pool;
        // If there already is a set saved for `idom`, just keep it.
        self.idom_sets.entry(idom).or_insert_with(|| {
            let mut list = ValueList::default();
            list.extend(values, pool);
            list
        });
    }
}
<|endoftext|>


<commit_before>#[macro_use]
mod macros;
mod error;
mod expression;
mod statement;
mod function;

use error::Error;
use arena::Arena;

use ast::{Loc, Ptr, Statement, RawList, List, ListBuilder, Parameter, ParameterList, OperatorKind};
use lexer::{Lexer, Token, Asi};
use lexer::Token::*;

pub struct Parser<'ast> {
    arena: &'ast Arena,

    /// Lexer will produce tokens from the source
    lexer: Lexer<'ast>,

    /// Set to `Some` whenever peek is called
    token: Option<Token<'ast>>,

    /// Errors occurred during parsing
    errors: Vec<Error>,

    /// AST under construction
    body: List<'ast, Loc<Statement<'ast>>>,
}

impl<'ast> Parser<'ast> {
    pub fn new(source: &'ast str, arena: &'ast Arena) -> Self {
        Parser {
            arena,
            lexer: Lexer::new(source),
            token: None,
            errors: Vec::new(),
            body: List::empty(),
        }
    }

    /// Get the next token.
    #[inline]
    fn next(&mut self) -> Token<'ast> {
        match self.token {
            None => self.lexer.get_token(),

            Some(token) => {
                self.token = None;

                token
            }
        }
    }

    /// Peek on the next token.
    #[inline]
    fn peek(&mut self) -> Token<'ast> {
        match self.token {
            None => {
                let token = self.lexer.get_token();

                self.token = Some(token);

                token
            },

            Some(token) => token
        }
    }

    #[inline]
    fn asi(&mut self) -> Asi {
        self.peek();

        self.lexer.asi()
    }

    #[inline]
    fn consume(&mut self) {
        self.token = None;
    }

    #[inline]
    fn loc(&self) -> (u32, u32) {
        self.lexer.loc()
    }

    #[inline]
    fn in_loc<T>(&self, item: T) -> Loc<T> {
        let (start, end) = self.loc();

        Loc::new(start, end, item)
    }

    #[inline]
    fn alloc<T>(&mut self, val: T) -> Ptr<'ast, T> {
        Ptr::new(self.arena.alloc(val))
    }

    #[inline]
    fn alloc_in_loc<T>(&mut self, item: T) -> Ptr<'ast, Loc<T>> {
        let node = self.in_loc(item);
        self.alloc(node)
    }

    #[inline]
    fn parse(&mut self) {
        let statement = match self.next() {
            EndOfProgram => return,
            token        => self.statement(token)
        };

        let mut builder = ListBuilder::new(self.arena, statement);

        loop {
            let statement = match self.next() {
                EndOfProgram => break,
                token        => self.statement(token)
            };

            builder.push(statement);
        }

        self.body = builder.into_list()
    }

    #[inline]
    fn block_body_tail(&mut self) -> List<'ast, Loc<Statement<'ast>>> {
        let statement = match self.next() {
            BraceClose => return List::empty(),
            token      => self.statement(token),
        };

        let mut builder = ListBuilder::new(self.arena, statement);

        loop {
            let statement = match self.next() {
                BraceClose => break,
                token      => self.statement(token),
            };

            builder.push(statement);
        }

        builder.into_list()
    }

    #[inline]
    fn block_body(&mut self) -> List<'ast, Loc<Statement<'ast>>> {
        expect!(self, BraceOpen);
        self.block_body_tail()
    }

    #[inline]
    fn parameter_list(&mut self) -> ParameterList<'ast> {
        let mut default_params = false;
        let first = match self.next() {
            Identifier(label) => {
                let parameter = Parameter::Identifier {
                    label,
                    value: match self.peek() {
                        Token::Operator(OperatorKind::Assign) => {
                            self.consume();
                            let expr = self.expression(0);
                            default_params = true;
                            Some(self.alloc(expr))
                        },
                        _ => None
                    }
                };
                self.in_loc(parameter)
            },
            ParenClose       => return List::empty(),
            _                => unexpected_token!(self),
        };

        let mut builder = ListBuilder::new(self.arena, first);

        loop {
            match self.next() {
                ParenClose => break,
                Comma      => {},
                _          => unexpected_token!(self),
            };

            match self.next() {
                ParenClose        => break,
                Identifier(label) => {
                    let parameter = Parameter::Identifier {
                        label,
                        value: match self.peek() {
                            Token::Operator(OperatorKind::Assign) => {
                                self.consume();
                                let expr = self.expression(0);
                                default_params = true;
                                Some(self.alloc(expr))
                            },
                            _ => {
                                if default_params {
                                    unexpected_token!(self)
                                }
                                None
                            }
                        }
                    };

                    builder.push(self.in_loc(parameter));
                },
                _ => unexpected_token!(self)
            }
        }

        builder.into_list()
    }
}

pub struct Module {
    body: RawList,
    arena: Arena,
}

impl Module {
    pub fn body<'ast>(&'ast self) -> List<'ast, Loc<Statement<'ast>>> {
        unsafe { self.body.into_list() }
    }

    pub fn arena(&self) -> &Arena {
        &self.arena
    }
}

pub fn parse(source: &str) -> Result<Module, Vec<Error>> {
    let arena = Arena::new();

    let (body, errors) = {
        let source = arena.alloc_str(source);
        let mut parser = Parser::new(source, &arena);

        parser.parse();

        (parser.body.into_raw(), parser.errors)
    };

    match errors.len() {
        0 => Ok(Module { body, arena }),
        _ => Err(errors)
    }
}

#[cfg(test)]
mod mock {
    use super::*;
    use ast::{Expression, Value};

    pub struct Mock {
        arena: Arena
    }

    impl Mock {
        pub fn new() -> Self {
            Mock {
                arena: Arena::new()
            }
        }

        pub fn ptr<'a, T: 'a>(&'a self, val: T) -> Ptr<'a, Loc<T>> {
            Ptr::new(self.arena.alloc(Loc::new(0, 0, val)))
        }

        pub fn ident<'a>(&'a self, ident: &'static str) -> Ptr<'a, Loc<Expression<'a>>> {
            self.ptr(Expression::Identifier(ident))
        }

        pub fn number<'a>(&'a self, number: &'static str) -> Ptr<'a, Loc<Expression<'a>>> {
            self.ptr(Expression::Value(Value::Number(number)))
        }

        pub fn list<'a, T, L>(&'a self, list: L) -> List<'a, Loc<T>> where
            T: 'a + Clone,
            L: AsRef<[T]>
        {
            List::from_iter(&self.arena, list.as_ref().iter().cloned().map(|i| Loc::new(0, 0, i)))
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use parser::mock::Mock;

    #[test]
    fn empty_parse() {
        let module = parse("").unwrap();

        assert_eq!(module.body(), List::empty());
    }

    #[test]
    fn empty_statements() {
        let module = parse(";;;").unwrap();
        let mock = Mock::new();

        let expected = mock.list([
            Statement::Empty,
            Statement::Empty,
            Statement::Empty
        ]);

        assert_eq!(module.body(), expected);
    }

}
<commit_msg>Implementing review feedback<commit_after>#[macro_use]
mod macros;
mod error;
mod expression;
mod statement;
mod function;

use error::Error;
use arena::Arena;

use ast::{Loc, Ptr, Statement, RawList, List, ListBuilder, EmptyListBuilder, Parameter, ParameterList, OperatorKind};
use lexer::{Lexer, Token, Asi};
use lexer::Token::*;

pub struct Parser<'ast> {
    arena: &'ast Arena,

    /// Lexer will produce tokens from the source
    lexer: Lexer<'ast>,

    /// Set to `Some` whenever peek is called
    token: Option<Token<'ast>>,

    /// Errors occurred during parsing
    errors: Vec<Error>,

    /// AST under construction
    body: List<'ast, Loc<Statement<'ast>>>,
}

impl<'ast> Parser<'ast> {
    pub fn new(source: &'ast str, arena: &'ast Arena) -> Self {
        Parser {
            arena,
            lexer: Lexer::new(source),
            token: None,
            errors: Vec::new(),
            body: List::empty(),
        }
    }

    /// Get the next token.
    #[inline]
    fn next(&mut self) -> Token<'ast> {
        match self.token {
            None => self.lexer.get_token(),

            Some(token) => {
                self.token = None;

                token
            }
        }
    }

    /// Peek on the next token.
    #[inline]
    fn peek(&mut self) -> Token<'ast> {
        match self.token {
            None => {
                let token = self.lexer.get_token();

                self.token = Some(token);

                token
            },

            Some(token) => token
        }
    }

    #[inline]
    fn asi(&mut self) -> Asi {
        self.peek();

        self.lexer.asi()
    }

    #[inline]
    fn consume(&mut self) {
        self.token = None;
    }

    #[inline]
    fn loc(&self) -> (u32, u32) {
        self.lexer.loc()
    }

    #[inline]
    fn in_loc<T>(&self, item: T) -> Loc<T> {
        let (start, end) = self.loc();

        Loc::new(start, end, item)
    }

    #[inline]
    fn alloc<T>(&mut self, val: T) -> Ptr<'ast, T> {
        Ptr::new(self.arena.alloc(val))
    }

    #[inline]
    fn alloc_in_loc<T>(&mut self, item: T) -> Ptr<'ast, Loc<T>> {
        let node = self.in_loc(item);
        self.alloc(node)
    }

    #[inline]
    fn parse(&mut self) {
        let statement = match self.next() {
            EndOfProgram => return,
            token        => self.statement(token)
        };

        let mut builder = ListBuilder::new(self.arena, statement);

        loop {
            let statement = match self.next() {
                EndOfProgram => break,
                token        => self.statement(token)
            };

            builder.push(statement);
        }

        self.body = builder.into_list()
    }

    #[inline]
    fn block_body_tail(&mut self) -> List<'ast, Loc<Statement<'ast>>> {
        let statement = match self.next() {
            BraceClose => return List::empty(),
            token      => self.statement(token),
        };

        let mut builder = ListBuilder::new(self.arena, statement);

        loop {
            let statement = match self.next() {
                BraceClose => break,
                token      => self.statement(token),
            };

            builder.push(statement);
        }

        builder.into_list()
    }

    #[inline]
    fn block_body(&mut self) -> List<'ast, Loc<Statement<'ast>>> {
        expect!(self, BraceOpen);
        self.block_body_tail()
    }

    #[inline]
    fn parameter_list(&mut self) -> ParameterList<'ast> {
        let mut default_params = false;
        let mut builder = EmptyListBuilder::new(self.arena);

        loop {
            match self.next() {
                ParenClose        => break,
                Identifier(label) => {
                    let parameter = Parameter::Identifier {
                        label,
                        value: match self.peek() {
                            Token::Operator(OperatorKind::Assign) => {
                                self.consume();
                                let expr = self.expression(0);
                                default_params = true;
                                Some(self.alloc(expr))
                            },
                            _ => {
                                if default_params {
                                    unexpected_token!(self)
                                }
                                None
                            }
                        }
                    };

                    builder.push(self.in_loc(parameter));
                },
                _ => unexpected_token!(self)
            }
            match self.next() {
                ParenClose => break,
                Comma      => {},
                _          => unexpected_token!(self),
            };
        }

        builder.into_list()
    }
}

pub struct Module {
    body: RawList,
    arena: Arena,
}

impl Module {
    pub fn body<'ast>(&'ast self) -> List<'ast, Loc<Statement<'ast>>> {
        unsafe { self.body.into_list() }
    }

    pub fn arena(&self) -> &Arena {
        &self.arena
    }
}

pub fn parse(source: &str) -> Result<Module, Vec<Error>> {
    let arena = Arena::new();

    let (body, errors) = {
        let source = arena.alloc_str(source);
        let mut parser = Parser::new(source, &arena);

        parser.parse();

        (parser.body.into_raw(), parser.errors)
    };

    match errors.len() {
        0 => Ok(Module { body, arena }),
        _ => Err(errors)
    }
}

#[cfg(test)]
mod mock {
    use super::*;
    use ast::{Expression, Value};

    pub struct Mock {
        arena: Arena
    }

    impl Mock {
        pub fn new() -> Self {
            Mock {
                arena: Arena::new()
            }
        }

        pub fn ptr<'a, T: 'a>(&'a self, val: T) -> Ptr<'a, Loc<T>> {
            Ptr::new(self.arena.alloc(Loc::new(0, 0, val)))
        }

        pub fn ident<'a>(&'a self, ident: &'static str) -> Ptr<'a, Loc<Expression<'a>>> {
            self.ptr(Expression::Identifier(ident))
        }

        pub fn number<'a>(&'a self, number: &'static str) -> Ptr<'a, Loc<Expression<'a>>> {
            self.ptr(Expression::Value(Value::Number(number)))
        }

        pub fn list<'a, T, L>(&'a self, list: L) -> List<'a, Loc<T>> where
            T: 'a + Clone,
            L: AsRef<[T]>
        {
            List::from_iter(&self.arena, list.as_ref().iter().cloned().map(|i| Loc::new(0, 0, i)))
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use parser::mock::Mock;

    #[test]
    fn empty_parse() {
        let module = parse("").unwrap();

        assert_eq!(module.body(), List::empty());
    }

    #[test]
    fn empty_statements() {
        let module = parse(";;;").unwrap();
        let mock = Mock::new();

        let expected = mock.list([
            Statement::Empty,
            Statement::Empty,
            Statement::Empty
        ]);

        assert_eq!(module.body(), expected);
    }

}
<|endoftext|>


<commit_before>// This file is part of libfringe, a low-level green threading library.
// Copyright (c) whitequark <whitequark@whitequark.org>
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://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.

//! Generators.
//!
//! Generators allow repeatedly suspending the execution of a function,
//! returning a value to the caller, and resuming the suspended function
//! afterwards.

use core::marker::PhantomData;
use core::{ptr, mem};
use core::cell::Cell;

use stack;
use debug;
use arch::{self, StackPointer};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum State {
  /// Generator can be resumed. This is the initial state.
  Runnable,
  /// Generator cannot be resumed. This is the state of the generator after
  /// the generator function has returned or panicked.
  Unavailable
}

/// Generator wraps a function and allows suspending its execution more than once, returning
/// a value each time.
///
/// The first time `resume(input0)` is called, the function is called as `f(yielder, input0)`.
/// It runs until it suspends its execution through `yielder.suspend(output0)`, after which
/// `resume(input0)` returns `output0`. The function can be resumed again using `resume(input1)`,
/// after which `yielder.suspend(output0)` returns `input1`, and so on. Once the function returns,
/// the `resume()` call will return `None`, and it will return `None` every time it is called
/// after that.
///
/// If the generator function panics, the panic is propagated through the `resume()` call as usual.
///
/// After the generator function returns or panics, it is safe to reclaim the generator stack
/// using `unwrap()`.
///
/// `state()` can be used to determine whether the generator function has returned;
/// the state is `State::Runnable` after creation and suspension, and `State::Unavailable`
/// once the generator function returns or panics.
///
/// When the input type is `()`, a generator implements the Iterator trait.
///
/// # Example
///
/// ```
/// use fringe::{OsStack, Generator};
///
/// let stack = OsStack::new(0).unwrap();
/// let mut add_one = Generator::new(stack, move |yielder, mut input| {
///   loop {
///     if input == 0 { break }
///     input = yielder.suspend(input + 1)
///   }
/// });
/// println!("{:?}", add_one.resume(2)); // prints Some(3)
/// println!("{:?}", add_one.resume(3)); // prints Some(4)
/// println!("{:?}", add_one.resume(0)); // prints None
/// ```
///
/// # Iterator example
///
/// ```
/// use fringe::{OsStack, Generator};
/// use std::mem;
///
/// let stack = OsStack::new(0).unwrap();
/// let mut nat = Generator::new(stack, move |yielder, ()| {
///   for i in 1.. { yielder.suspend(i) }
/// });
/// println!("{:?}", nat.next()); // prints Some(0)
/// println!("{:?}", nat.next()); // prints Some(1)
/// println!("{:?}", nat.next()); // prints Some(2)
/// mem::forget(nat); // we can't drop a running Generator, so we leak it
/// ```
#[derive(Debug)]
pub struct Generator<'a, Input: 'a, Output: 'a, Stack: stack::Stack> {
  state:     State,
  stack:     NoDrop<Stack>,
  stack_id:  NoDrop<debug::StackId>,
  stack_ptr: arch::StackPointer,
  phantom:   PhantomData<(&'a (), *mut Input, *const Output)>
}

#[allow(unions_with_drop_fields)]
union NoDrop<T> {
  value: T,
  _empty: ()
}

impl<T: ::core::fmt::Debug> ::core::fmt::Debug for NoDrop<T> {
  fn fmt(&self, w: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
    unsafe {
      // this is safe because we never invoke formatting on the empty variant
      self.value.fmt(w)
    }
  }
}

impl<'a, Input, Output, Stack> Generator<'a, Input, Output, Stack>
    where Input: 'a, Output: 'a, Stack: stack::Stack {
  /// Creates a new generator.
  ///
  /// See also the [contract](../trait.GuardedStack.html) that needs to be fulfilled by `stack`.
  pub fn new<F>(stack: Stack, f: F) -> Generator<'a, Input, Output, Stack>
      where Stack: stack::GuardedStack,
            F: FnOnce(&Yielder<Input, Output>, Input) + 'a {
    unsafe { Generator::unsafe_new(stack, f) }
  }

  /// Same as `new`, but does not require `stack` to have a guard page.
  ///
  /// This function is unsafe because the generator function can easily violate
  /// memory safety by overflowing the stack. It is useful in environments where
  /// guarded stacks do not exist, e.g. in absence of an MMU.
  ///
  /// See also the [contract](../trait.Stack.html) that needs to be fulfilled by `stack`.
  pub unsafe fn unsafe_new<F>(stack: Stack, f: F) -> Generator<'a, Input, Output, Stack>
      where F: FnOnce(&Yielder<Input, Output>, Input) + 'a {
    unsafe extern "C" fn generator_wrapper<Input, Output, Stack, F>(env: usize, stack_ptr: StackPointer) -> !
        where Stack: stack::Stack, F: FnOnce(&Yielder<Input, Output>, Input) {
      // Retrieve our environment from the callee and return control to it.
      let f = ptr::read(env as *const F);
      let (data, stack_ptr) = arch::swap(0, stack_ptr, None);
      // See the second half of Yielder::suspend_bare.
      let input = ptr::read(data as *const Input);
      // Run the body of the generator.
      let yielder = Yielder::new(stack_ptr);
      f(&yielder, input);
      // Past this point, the generator has dropped everything it has held.
      loop { yielder.suspend_bare(None); }
    }

    let stack_id  = debug::StackId::register(&stack);
    let stack_ptr = arch::init(&stack, generator_wrapper::<Input, Output, Stack, F>);

    // Transfer environment to the callee.
    let stack_ptr = arch::swap(&f as *const F as usize, stack_ptr, Some(&stack)).1;
    mem::forget(f);

    Generator {
      state:     State::Runnable,
      stack:     NoDrop { value: stack },
      stack_id:  NoDrop { value: stack_id },
      stack_ptr: stack_ptr,
      phantom:   PhantomData
    }
  }

  /// Resumes the generator and return the next value it yields.
  /// If the generator function has returned, returns `None`.
  #[inline]
  pub fn resume(&mut self, input: Input) -> Option<Output> {
    match self.state {
      State::Runnable => {
        // Set the state to Unavailable. Since we have exclusive access to the generator,
        // the only case where this matters is the generator function panics, after which
        // it must not be invocable again.
        self.state = State::Unavailable;

        // Switch to the generator function, and retrieve the yielded value.
        let val = unsafe {
          let (data_out, stack_ptr) = arch::swap(&input as *const Input as usize, self.stack_ptr, Some(&self.stack.value));
          self.stack_ptr = stack_ptr;
          mem::forget(input);
          ptr::read(data_out as *const Option<Output>)
        };

        // Unless the generator function has returned, it can be switched to again, so
        // set the state to Runnable.
        if val.is_some() { self.state = State::Runnable }

        val
      }
      State::Unavailable => None
    }
  }

  /// Returns the state of the generator.
  #[inline]
  pub fn state(&self) -> State { self.state }

  /// Extracts the stack from a generator when the generator function has returned.
  /// If the generator function has not returned
  /// (i.e. `self.state() == State::Runnable`), panics.
  pub fn unwrap(self) -> Stack {
    match self.state {
      State::Runnable => {
        mem::forget(self);
        panic!("Argh! Bastard! Don't touch that!")
      }
      State::Unavailable => unsafe { self.unsafe_unwrap() }
    }
  }

  unsafe fn unsafe_unwrap(mut self) -> Stack {
    ptr::drop_in_place(&mut self.stack_id.value);
    let stack = ptr::read(&mut self.stack.value);
    mem::forget(self);
    stack
  }
}

impl<'a, Input, Output, Stack> Drop for Generator<'a, Input, Output, Stack>
    where Input: 'a, Output: 'a, Stack: stack::Stack {
  fn drop(&mut self) {
    unsafe {
      ptr::drop_in_place(&mut self.stack_id.value);
      match self.state {
        State::Runnable    => panic!("dropped unfinished Generator"),
        State::Unavailable => ptr::drop_in_place(&mut self.stack.value)
      }
    }
  }
}

/// Yielder is an interface provided to every generator through which it
/// returns a value.
#[derive(Debug)]
pub struct Yielder<Input, Output> {
  stack_ptr: Cell<StackPointer>,
  phantom: PhantomData<(*const Input, *mut Output)>
}

impl<Input, Output> Yielder<Input, Output> {
  fn new(stack_ptr: StackPointer) -> Yielder<Input, Output> {
    Yielder {
      stack_ptr: Cell::new(stack_ptr),
      phantom: PhantomData
    }
  }

  #[inline(always)]
  fn suspend_bare(&self, val: Option<Output>) -> Input {
    unsafe {
      let (data, stack_ptr) = arch::swap(&val as *const Option<Output> as usize, self.stack_ptr.get(), None);
      self.stack_ptr.set(stack_ptr);
      mem::forget(val);
      ptr::read(data as *const Input)
    }
  }

  /// Suspends the generator and returns `Some(item)` from the `resume()`
  /// invocation that resumed the generator.
  #[inline(always)]
  pub fn suspend(&self, item: Output) -> Input {
    self.suspend_bare(Some(item))
  }
}

impl<'a, Output, Stack> Iterator for Generator<'a, (), Output, Stack>
    where Output: 'a, Stack: stack::Stack {
  type Item = Output;

  fn next(&mut self) -> Option<Self::Item> { self.resume(()) }
}
<commit_msg>Require Stack to be 'static<commit_after>// This file is part of libfringe, a low-level green threading library.
// Copyright (c) whitequark <whitequark@whitequark.org>
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://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.

//! Generators.
//!
//! Generators allow repeatedly suspending the execution of a function,
//! returning a value to the caller, and resuming the suspended function
//! afterwards.

use core::marker::PhantomData;
use core::{ptr, mem};
use core::cell::Cell;

use stack;
use debug;
use arch::{self, StackPointer};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum State {
  /// Generator can be resumed. This is the initial state.
  Runnable,
  /// Generator cannot be resumed. This is the state of the generator after
  /// the generator function has returned or panicked.
  Unavailable
}

/// Generator wraps a function and allows suspending its execution more than once, returning
/// a value each time.
///
/// The first time `resume(input0)` is called, the function is called as `f(yielder, input0)`.
/// It runs until it suspends its execution through `yielder.suspend(output0)`, after which
/// `resume(input0)` returns `output0`. The function can be resumed again using `resume(input1)`,
/// after which `yielder.suspend(output0)` returns `input1`, and so on. Once the function returns,
/// the `resume()` call will return `None`, and it will return `None` every time it is called
/// after that.
///
/// If the generator function panics, the panic is propagated through the `resume()` call as usual.
///
/// After the generator function returns or panics, it is safe to reclaim the generator stack
/// using `unwrap()`.
///
/// `state()` can be used to determine whether the generator function has returned;
/// the state is `State::Runnable` after creation and suspension, and `State::Unavailable`
/// once the generator function returns or panics.
///
/// When the input type is `()`, a generator implements the Iterator trait.
///
/// # Example
///
/// ```
/// use fringe::{OsStack, Generator};
///
/// let stack = OsStack::new(0).unwrap();
/// let mut add_one = Generator::new(stack, move |yielder, mut input| {
///   loop {
///     if input == 0 { break }
///     input = yielder.suspend(input + 1)
///   }
/// });
/// println!("{:?}", add_one.resume(2)); // prints Some(3)
/// println!("{:?}", add_one.resume(3)); // prints Some(4)
/// println!("{:?}", add_one.resume(0)); // prints None
/// ```
///
/// # Iterator example
///
/// ```
/// use fringe::{OsStack, Generator};
/// use std::mem;
///
/// let stack = OsStack::new(0).unwrap();
/// let mut nat = Generator::new(stack, move |yielder, ()| {
///   for i in 1.. { yielder.suspend(i) }
/// });
/// println!("{:?}", nat.next()); // prints Some(0)
/// println!("{:?}", nat.next()); // prints Some(1)
/// println!("{:?}", nat.next()); // prints Some(2)
/// mem::forget(nat); // we can't drop a running Generator, so we leak it
/// ```
#[derive(Debug)]
pub struct Generator<'a, Input: 'a, Output: 'a, Stack: stack::Stack> {
  state:     State,
  stack:     NoDrop<Stack>,
  stack_id:  NoDrop<debug::StackId>,
  stack_ptr: arch::StackPointer,
  phantom:   PhantomData<(&'a (), *mut Input, *const Output)>
}

#[allow(unions_with_drop_fields)]
union NoDrop<T> {
  value: T,
  _empty: ()
}

impl<T: ::core::fmt::Debug> ::core::fmt::Debug for NoDrop<T> {
  fn fmt(&self, w: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
    unsafe {
      // this is safe because we never invoke formatting on the empty variant
      self.value.fmt(w)
    }
  }
}

impl<'a, Input, Output, Stack> Generator<'a, Input, Output, Stack>
    where Input: 'a, Output: 'a, Stack: stack::Stack {
  /// Creates a new generator.
  ///
  /// See also the [contract](../trait.GuardedStack.html) that needs to be fulfilled by `stack`.
  pub fn new<F>(stack: Stack, f: F) -> Generator<'a, Input, Output, Stack>
      where Stack: stack::GuardedStack + 'static,
            F: FnOnce(&Yielder<Input, Output>, Input) + 'a {
    unsafe { Generator::unsafe_new(stack, f) }
  }

  /// Same as `new`, but does not require `stack` to have a guard page.
  ///
  /// This function is unsafe because the generator function can easily violate
  /// memory safety by overflowing the stack. It is useful in environments where
  /// guarded stacks do not exist, e.g. in absence of an MMU.
  ///
  /// See also the [contract](../trait.Stack.html) that needs to be fulfilled by `stack`.
  pub unsafe fn unsafe_new<F>(stack: Stack, f: F) -> Generator<'a, Input, Output, Stack>
      where F: FnOnce(&Yielder<Input, Output>, Input) + 'a {
    unsafe extern "C" fn generator_wrapper<Input, Output, Stack, F>(env: usize, stack_ptr: StackPointer) -> !
        where Stack: stack::Stack, F: FnOnce(&Yielder<Input, Output>, Input) {
      // Retrieve our environment from the callee and return control to it.
      let f = ptr::read(env as *const F);
      let (data, stack_ptr) = arch::swap(0, stack_ptr, None);
      // See the second half of Yielder::suspend_bare.
      let input = ptr::read(data as *const Input);
      // Run the body of the generator.
      let yielder = Yielder::new(stack_ptr);
      f(&yielder, input);
      // Past this point, the generator has dropped everything it has held.
      loop { yielder.suspend_bare(None); }
    }

    let stack_id  = debug::StackId::register(&stack);
    let stack_ptr = arch::init(&stack, generator_wrapper::<Input, Output, Stack, F>);

    // Transfer environment to the callee.
    let stack_ptr = arch::swap(&f as *const F as usize, stack_ptr, Some(&stack)).1;
    mem::forget(f);

    Generator {
      state:     State::Runnable,
      stack:     NoDrop { value: stack },
      stack_id:  NoDrop { value: stack_id },
      stack_ptr: stack_ptr,
      phantom:   PhantomData
    }
  }

  /// Resumes the generator and return the next value it yields.
  /// If the generator function has returned, returns `None`.
  #[inline]
  pub fn resume(&mut self, input: Input) -> Option<Output> {
    match self.state {
      State::Runnable => {
        // Set the state to Unavailable. Since we have exclusive access to the generator,
        // the only case where this matters is the generator function panics, after which
        // it must not be invocable again.
        self.state = State::Unavailable;

        // Switch to the generator function, and retrieve the yielded value.
        let val = unsafe {
          let (data_out, stack_ptr) = arch::swap(&input as *const Input as usize, self.stack_ptr, Some(&self.stack.value));
          self.stack_ptr = stack_ptr;
          mem::forget(input);
          ptr::read(data_out as *const Option<Output>)
        };

        // Unless the generator function has returned, it can be switched to again, so
        // set the state to Runnable.
        if val.is_some() { self.state = State::Runnable }

        val
      }
      State::Unavailable => None
    }
  }

  /// Returns the state of the generator.
  #[inline]
  pub fn state(&self) -> State { self.state }

  /// Extracts the stack from a generator when the generator function has returned.
  /// If the generator function has not returned
  /// (i.e. `self.state() == State::Runnable`), panics.
  pub fn unwrap(self) -> Stack {
    match self.state {
      State::Runnable => {
        mem::forget(self);
        panic!("Argh! Bastard! Don't touch that!")
      }
      State::Unavailable => unsafe { self.unsafe_unwrap() }
    }
  }

  unsafe fn unsafe_unwrap(mut self) -> Stack {
    ptr::drop_in_place(&mut self.stack_id.value);
    let stack = ptr::read(&mut self.stack.value);
    mem::forget(self);
    stack
  }
}

impl<'a, Input, Output, Stack> Drop for Generator<'a, Input, Output, Stack>
    where Input: 'a, Output: 'a, Stack: stack::Stack {
  fn drop(&mut self) {
    unsafe {
      ptr::drop_in_place(&mut self.stack_id.value);
      match self.state {
        State::Runnable    => panic!("dropped unfinished Generator"),
        State::Unavailable => ptr::drop_in_place(&mut self.stack.value)
      }
    }
  }
}

/// Yielder is an interface provided to every generator through which it
/// returns a value.
#[derive(Debug)]
pub struct Yielder<Input, Output> {
  stack_ptr: Cell<StackPointer>,
  phantom: PhantomData<(*const Input, *mut Output)>
}

impl<Input, Output> Yielder<Input, Output> {
  fn new(stack_ptr: StackPointer) -> Yielder<Input, Output> {
    Yielder {
      stack_ptr: Cell::new(stack_ptr),
      phantom: PhantomData
    }
  }

  #[inline(always)]
  fn suspend_bare(&self, val: Option<Output>) -> Input {
    unsafe {
      let (data, stack_ptr) = arch::swap(&val as *const Option<Output> as usize, self.stack_ptr.get(), None);
      self.stack_ptr.set(stack_ptr);
      mem::forget(val);
      ptr::read(data as *const Input)
    }
  }

  /// Suspends the generator and returns `Some(item)` from the `resume()`
  /// invocation that resumed the generator.
  #[inline(always)]
  pub fn suspend(&self, item: Output) -> Input {
    self.suspend_bare(Some(item))
  }
}

impl<'a, Output, Stack> Iterator for Generator<'a, (), Output, Stack>
    where Output: 'a, Stack: stack::Stack {
  type Item = Output;

  fn next(&mut self) -> Option<Self::Item> { self.resume(()) }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

use {
    TexturePackerAlrogithm,
    TexturePackerConfig,
};

use texture::{
    Pixel,
    Texture,
};

use frame::Frame;
use packer::{
    Packer,
    SkylinePacker,
};

pub struct TexturePacker<'a, P: Pixel> {
    textures: HashMap<String, Box<Texture<Pixel = P> + 'a>>,
    frames: HashMap<String, Frame>,
    packer: Box<Packer<Pixel = P> + 'a>,
    config: TexturePackerConfig,
}

impl<'a, P: Pixel> TexturePacker<'a, P> {
    pub fn new(config: TexturePackerConfig) -> TexturePacker<'a, P> {
        let packer = match config.algorithm {
            TexturePackerAlrogithm::Skyline => {
                Box::new(SkylinePacker::new(config))
            }
        };

        TexturePacker {
            textures: HashMap::new(),
            frames: HashMap::new(),
            packer: packer,
            config: config,
        }
    }

    pub fn pack(&mut self, key: String, texture: Box<Texture<Pixel = P> + 'a>) {
        if let Some(mut frame) = self.packer.pack(key.clone(), &*texture) {
            frame.frame.x += self.config.border_padding;
            frame.frame.y += self.config.border_padding;
            self.frames.insert(key.clone(), frame);
        }

        self.textures.insert(key, texture);
    }

    pub fn get_frames(&self) -> HashMap<String, Frame> {
        self.frames.clone()
    }

    pub fn get_frame(&self, key: &str) -> Option<Frame> {
        if let Some(frame) = self.frames.get(key) {
            Some(frame.clone())
        } else {
            None
        }
    }

    fn get_frame_at(&self, x: u32, y: u32) -> Option<&Frame> {
        for (_, frame) in self.frames.iter() {
            if frame.frame.contains_point(x, y) {
                return Some(frame);
            }
        }
        None
    }
}

impl<'a, P: Pixel> Texture for TexturePacker<'a, P> {
    type Pixel = P;

    fn width(&self) -> u32 {
        let mut right = 0;

        for (_, frame) in self.frames.iter() {
            if frame.frame.right() > right {
                right = frame.frame.right();
            }
        }

        right + 1 + self.config.border_padding
    }

    fn height(&self) -> u32 {
        let mut bottom = 0;

        for (_, frame) in self.frames.iter() {
            if frame.frame.bottom() > bottom {
                bottom = frame.frame.bottom();
            }
        }

        bottom + 1 + self.config.border_padding
    }

    fn get(&self, x: u32, y: u32) -> Option<P> {
        use rect::Rect;
        let rect = Rect::new(0, 0, self.width(), self.height());
        if rect.is_outline(x, y) {
            return Some(<P as Pixel>::outline());
        }

        if let Some(frame) = self.get_frame_at(x, y) {
            if let Some(texture) = self.textures.get(&frame.key) {
                if self.config.texture_outlines && frame.frame.is_outline(x, y) {
                    return Some(<P as Pixel>::outline());
                }

                let x = x - frame.frame.x;
                let y = y - frame.frame.y;

                return if frame.rotated {
                    texture.get_rotated(x, y)
                } else {
                    texture.get(x, y)
                };
            }
        }

        None
    }

    fn set(&mut self, _x: u32, _y: u32, _val: P) {
        panic!("Can't set pixel directly");
    }
}
<commit_msg>Remove border outline<commit_after>use std::collections::HashMap;

use {
    TexturePackerAlrogithm,
    TexturePackerConfig,
};

use texture::{
    Pixel,
    Texture,
};

use frame::Frame;
use packer::{
    Packer,
    SkylinePacker,
};

pub struct TexturePacker<'a, P: Pixel> {
    textures: HashMap<String, Box<Texture<Pixel = P> + 'a>>,
    frames: HashMap<String, Frame>,
    packer: Box<Packer<Pixel = P> + 'a>,
    config: TexturePackerConfig,
}

impl<'a, P: Pixel> TexturePacker<'a, P> {
    pub fn new(config: TexturePackerConfig) -> TexturePacker<'a, P> {
        let packer = match config.algorithm {
            TexturePackerAlrogithm::Skyline => {
                Box::new(SkylinePacker::new(config))
            }
        };

        TexturePacker {
            textures: HashMap::new(),
            frames: HashMap::new(),
            packer: packer,
            config: config,
        }
    }

    pub fn pack(&mut self, key: String, texture: Box<Texture<Pixel = P> + 'a>) {
        if let Some(mut frame) = self.packer.pack(key.clone(), &*texture) {
            frame.frame.x += self.config.border_padding;
            frame.frame.y += self.config.border_padding;
            self.frames.insert(key.clone(), frame);
        }

        self.textures.insert(key, texture);
    }

    pub fn get_frames(&self) -> HashMap<String, Frame> {
        self.frames.clone()
    }

    pub fn get_frame(&self, key: &str) -> Option<Frame> {
        if let Some(frame) = self.frames.get(key) {
            Some(frame.clone())
        } else {
            None
        }
    }

    fn get_frame_at(&self, x: u32, y: u32) -> Option<&Frame> {
        for (_, frame) in self.frames.iter() {
            if frame.frame.contains_point(x, y) {
                return Some(frame);
            }
        }
        None
    }
}

impl<'a, P: Pixel> Texture for TexturePacker<'a, P> {
    type Pixel = P;

    fn width(&self) -> u32 {
        let mut right = 0;

        for (_, frame) in self.frames.iter() {
            if frame.frame.right() > right {
                right = frame.frame.right();
            }
        }

        right + 1 + self.config.border_padding
    }

    fn height(&self) -> u32 {
        let mut bottom = 0;

        for (_, frame) in self.frames.iter() {
            if frame.frame.bottom() > bottom {
                bottom = frame.frame.bottom();
            }
        }

        bottom + 1 + self.config.border_padding
    }

    fn get(&self, x: u32, y: u32) -> Option<P> {
        if let Some(frame) = self.get_frame_at(x, y) {
            if let Some(texture) = self.textures.get(&frame.key) {
                if self.config.texture_outlines && frame.frame.is_outline(x, y) {
                    return Some(<P as Pixel>::outline());
                }

                let x = x - frame.frame.x;
                let y = y - frame.frame.y;

                return if frame.rotated {
                    texture.get_rotated(x, y)
                } else {
                    texture.get(x, y)
                };
            }
        }

        None
    }

    fn set(&mut self, _x: u32, _y: u32, _val: P) {
        panic!("Can't set pixel directly");
    }
}
<|endoftext|>


<commit_before>use std::slice::Iter;

use Tree;
use Node;
use NodeId;
use tree::IteratorNew;

///
/// An Iterator over the ancestors of a `Node`.
///
/// Iterates over the ancestor `Node`s of a given `Node` in the `Tree`.  Each call to `next` will
/// return an immutable reference to the next `Node` up the `Tree`.
///
pub struct Ancestors<'a, T: 'a> {
    tree: &'a Tree<T>,
    node_id: Option<NodeId>,
}

impl<'a, T> IteratorNew<'a, T, Ancestors<'a, T>> for Ancestors<'a, T> {
    fn new(tree: &'a Tree<T>, node_id: NodeId) -> Ancestors<'a, T> {
        Ancestors {
            tree: tree,
            node_id: Some(node_id),
        }
    }
}

impl<'a, T> Iterator for Ancestors<'a, T> {
    type Item = &'a Node<T>;

    fn next(&mut self) -> Option<&'a Node<T>> {
        if let Some(current_id) = self.node_id.clone() {

            if let Some(parent_id) = self.tree.get_unsafe(&current_id).parent() {

                let parent = self.tree.get_unsafe(&parent_id);

                self.node_id = Some(parent_id.clone());

                return Some(parent);
            } else {
                self.node_id = None;
            }
        }
        None
    }
}

///
/// An Iterator over the ancestors of a `Node`.
///
/// Iterates over `NodeId`s instead of over the `Node`s themselves.
///
pub struct AncestorIds<'a, T: 'a> {
    tree: &'a Tree<T>,
    node_id: Option<NodeId>,
}

impl<'a, T> IteratorNew<'a, T, AncestorIds<'a, T>> for AncestorIds<'a, T> {
    fn new(tree: &'a Tree<T>, node_id: NodeId) -> AncestorIds<'a, T> {
        AncestorIds {
            tree: tree,
            node_id: Some(node_id),
        }
    }
}

impl<'a, T> Iterator for AncestorIds<'a, T> {
    type Item = &'a NodeId;

    fn next(&mut self) -> Option<&'a NodeId> {
        if let Some(current_id) = self.node_id.clone() {
            if let Some(parent_id) = self.tree.get_unsafe(&current_id).parent() {
                self.node_id = Some(parent_id.clone());
                return Some(parent_id);
            } else {
                self.node_id = None;
            }
        }
        None
    }
}

///
/// An Iterator over the children of a `Node`.
///
/// Iterates over the child `Node`s of a given `Node` in the `Tree`.  Each call to `next` will
/// return an immutable reference to the next child `Node`.
///
pub struct Children<'a, T: 'a> {
    tree: &'a Tree<T>,
    child_ids: Iter<'a, NodeId>,
}

impl<'a, T> IteratorNew<'a, T, Children<'a, T>> for Children<'a, T> {
    fn new(tree: &'a Tree<T>, node_id: NodeId) -> Children<'a, T> {
        Children {
            tree: tree,
            child_ids: tree.get_unsafe(&node_id).children().as_slice().iter(),
        }
    }
}

impl<'a, T> Iterator for Children<'a, T> {
    type Item = &'a Node<T>;

    fn next(&mut self) -> Option<&'a Node<T>> {
        if let Some(ref next_child_id) = self.child_ids.next() {
            return Some(self.tree.get_unsafe(next_child_id));
        }
        None
    }
}

///
/// An Iterator over the children of a `Node`.
///
/// Iterates over `NodeId`s instead of over the `Node`s themselves.
///
pub struct ChildrenIds<'a> {
    child_ids: Iter<'a, NodeId>,
}

impl<'a, T> IteratorNew<'a, T, ChildrenIds<'a>> for ChildrenIds<'a> {
    fn new(tree: &'a Tree<T>, node_id: NodeId) -> ChildrenIds<'a> {
        ChildrenIds { child_ids: tree.get_unsafe(&node_id).children().as_slice().iter() }
    }
}

impl<'a> Iterator for ChildrenIds<'a> {
    type Item = &'a NodeId;

    fn next(&mut self) -> Option<&'a NodeId> {
        self.child_ids.next()
    }
}

#[cfg(test)]
mod tests {

    use Tree;
    use Node;
    use InsertBehavior::*;

    #[test]
    fn test_ancestors() {
        let mut tree = Tree::new();

        let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
        let node_1 = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
        let node_2 = tree.insert(Node::new(2), UnderNode(&node_1)).unwrap();
        let node_3 = tree.insert(Node::new(3), UnderNode(&node_1)).unwrap();

        let ancestors = tree.ancestors(&root_id).unwrap();
        assert_eq!(ancestors.count(), 0);

        let data = [0];
        for (index, node) in tree.ancestors(&node_1).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }

        let data = [1, 0];
        for (index, node) in tree.ancestors(&node_2).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }

        let data = [1, 0];
        for (index, node) in tree.ancestors(&node_3).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }
    }

    #[test]
    fn test_ancestor_ids() {
        let mut tree = Tree::new();

        let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
        let node_1 = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
        let node_2 = tree.insert(Node::new(2), UnderNode(&node_1)).unwrap();
        let node_3 = tree.insert(Node::new(3), UnderNode(&node_1)).unwrap();

        let ancestor_ids = tree.ancestor_ids(&root_id).unwrap();
        assert_eq!(ancestor_ids.count(), 0);

        let data = [0];
        for (index, node_id) in tree.ancestor_ids(&node_1).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }

        let data = [1, 0];
        for (index, node_id) in tree.ancestor_ids(&node_2).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }

        let data = [1, 0];
        for (index, node_id) in tree.ancestor_ids(&node_3).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }
    }

    #[test]
    fn test_children() {
        let mut tree = Tree::new();

        let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
        let node_1 = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
        let node_2 = tree.insert(Node::new(2), UnderNode(&node_1)).unwrap();
        let node_3 = tree.insert(Node::new(3), UnderNode(&node_1)).unwrap();

        let data = [1];
        for (index, node) in tree.children(&root_id).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }

        let data = [2, 3];
        for (index, node) in tree.children(&node_1).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }

        let children = tree.children(&node_2).unwrap();
        assert_eq!(children.count(), 0);

        let children = tree.children(&node_3).unwrap();
        assert_eq!(children.count(), 0);
    }

    #[test]
    fn test_children_ids() {
        let mut tree = Tree::new();

        let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
        let node_1 = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
        let node_2 = tree.insert(Node::new(2), UnderNode(&node_1)).unwrap();
        let node_3 = tree.insert(Node::new(3), UnderNode(&node_1)).unwrap();

        let data = [1];
        for (index, node_id) in tree.children_ids(&root_id).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }

        let data = [2, 3];
        for (index, node_id) in tree.children_ids(&node_1).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }

        let children_ids = tree.children_ids(&node_2).unwrap();
        assert_eq!(children_ids.count(), 0);

        let children_ids = tree.children_ids(&node_3).unwrap();
        assert_eq!(children_ids.count(), 0);
    }
}
<commit_msg>remove some extra spaces<commit_after>use std::slice::Iter;

use Tree;
use Node;
use NodeId;
use tree::IteratorNew;

///
/// An Iterator over the ancestors of a `Node`.
///
/// Iterates over the ancestor `Node`s of a given `Node` in the `Tree`.  Each call to `next` will
/// return an immutable reference to the next `Node` up the `Tree`.
///
pub struct Ancestors<'a, T: 'a> {
    tree: &'a Tree<T>,
    node_id: Option<NodeId>,
}

impl<'a, T> IteratorNew<'a, T, Ancestors<'a, T>> for Ancestors<'a, T> {
    fn new(tree: &'a Tree<T>, node_id: NodeId) -> Ancestors<'a, T> {
        Ancestors {
            tree: tree,
            node_id: Some(node_id),
        }
    }
}

impl<'a, T> Iterator for Ancestors<'a, T> {
    type Item = &'a Node<T>;

    fn next(&mut self) -> Option<&'a Node<T>> {
        if let Some(current_id) = self.node_id.clone() {
            if let Some(parent_id) = self.tree.get_unsafe(&current_id).parent() {
                let parent = self.tree.get_unsafe(&parent_id);
                self.node_id = Some(parent_id.clone());
                return Some(parent);
            } else {
                self.node_id = None;
            }
        }
        None
    }
}

///
/// An Iterator over the ancestors of a `Node`.
///
/// Iterates over `NodeId`s instead of over the `Node`s themselves.
///
pub struct AncestorIds<'a, T: 'a> {
    tree: &'a Tree<T>,
    node_id: Option<NodeId>,
}

impl<'a, T> IteratorNew<'a, T, AncestorIds<'a, T>> for AncestorIds<'a, T> {
    fn new(tree: &'a Tree<T>, node_id: NodeId) -> AncestorIds<'a, T> {
        AncestorIds {
            tree: tree,
            node_id: Some(node_id),
        }
    }
}

impl<'a, T> Iterator for AncestorIds<'a, T> {
    type Item = &'a NodeId;

    fn next(&mut self) -> Option<&'a NodeId> {
        if let Some(current_id) = self.node_id.clone() {
            if let Some(parent_id) = self.tree.get_unsafe(&current_id).parent() {
                self.node_id = Some(parent_id.clone());
                return Some(parent_id);
            } else {
                self.node_id = None;
            }
        }
        None
    }
}

///
/// An Iterator over the children of a `Node`.
///
/// Iterates over the child `Node`s of a given `Node` in the `Tree`.  Each call to `next` will
/// return an immutable reference to the next child `Node`.
///
pub struct Children<'a, T: 'a> {
    tree: &'a Tree<T>,
    child_ids: Iter<'a, NodeId>,
}

impl<'a, T> IteratorNew<'a, T, Children<'a, T>> for Children<'a, T> {
    fn new(tree: &'a Tree<T>, node_id: NodeId) -> Children<'a, T> {
        Children {
            tree: tree,
            child_ids: tree.get_unsafe(&node_id).children().as_slice().iter(),
        }
    }
}

impl<'a, T> Iterator for Children<'a, T> {
    type Item = &'a Node<T>;

    fn next(&mut self) -> Option<&'a Node<T>> {
        if let Some(ref next_child_id) = self.child_ids.next() {
            return Some(self.tree.get_unsafe(next_child_id));
        }
        None
    }
}

///
/// An Iterator over the children of a `Node`.
///
/// Iterates over `NodeId`s instead of over the `Node`s themselves.
///
pub struct ChildrenIds<'a> {
    child_ids: Iter<'a, NodeId>,
}

impl<'a, T> IteratorNew<'a, T, ChildrenIds<'a>> for ChildrenIds<'a> {
    fn new(tree: &'a Tree<T>, node_id: NodeId) -> ChildrenIds<'a> {
        ChildrenIds { child_ids: tree.get_unsafe(&node_id).children().as_slice().iter() }
    }
}

impl<'a> Iterator for ChildrenIds<'a> {
    type Item = &'a NodeId;

    fn next(&mut self) -> Option<&'a NodeId> {
        self.child_ids.next()
    }
}

#[cfg(test)]
mod tests {

    use Tree;
    use Node;
    use InsertBehavior::*;

    #[test]
    fn test_ancestors() {
        let mut tree = Tree::new();

        let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
        let node_1 = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
        let node_2 = tree.insert(Node::new(2), UnderNode(&node_1)).unwrap();
        let node_3 = tree.insert(Node::new(3), UnderNode(&node_1)).unwrap();

        let ancestors = tree.ancestors(&root_id).unwrap();
        assert_eq!(ancestors.count(), 0);

        let data = [0];
        for (index, node) in tree.ancestors(&node_1).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }

        let data = [1, 0];
        for (index, node) in tree.ancestors(&node_2).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }

        let data = [1, 0];
        for (index, node) in tree.ancestors(&node_3).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }
    }

    #[test]
    fn test_ancestor_ids() {
        let mut tree = Tree::new();

        let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
        let node_1 = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
        let node_2 = tree.insert(Node::new(2), UnderNode(&node_1)).unwrap();
        let node_3 = tree.insert(Node::new(3), UnderNode(&node_1)).unwrap();

        let ancestor_ids = tree.ancestor_ids(&root_id).unwrap();
        assert_eq!(ancestor_ids.count(), 0);

        let data = [0];
        for (index, node_id) in tree.ancestor_ids(&node_1).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }

        let data = [1, 0];
        for (index, node_id) in tree.ancestor_ids(&node_2).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }

        let data = [1, 0];
        for (index, node_id) in tree.ancestor_ids(&node_3).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }
    }

    #[test]
    fn test_children() {
        let mut tree = Tree::new();

        let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
        let node_1 = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
        let node_2 = tree.insert(Node::new(2), UnderNode(&node_1)).unwrap();
        let node_3 = tree.insert(Node::new(3), UnderNode(&node_1)).unwrap();

        let data = [1];
        for (index, node) in tree.children(&root_id).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }

        let data = [2, 3];
        for (index, node) in tree.children(&node_1).unwrap().enumerate() {
            assert_eq!(node.data(), &data[index]);
        }

        let children = tree.children(&node_2).unwrap();
        assert_eq!(children.count(), 0);

        let children = tree.children(&node_3).unwrap();
        assert_eq!(children.count(), 0);
    }

    #[test]
    fn test_children_ids() {
        let mut tree = Tree::new();

        let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
        let node_1 = tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
        let node_2 = tree.insert(Node::new(2), UnderNode(&node_1)).unwrap();
        let node_3 = tree.insert(Node::new(3), UnderNode(&node_1)).unwrap();

        let data = [1];
        for (index, node_id) in tree.children_ids(&root_id).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }

        let data = [2, 3];
        for (index, node_id) in tree.children_ids(&node_1).unwrap().enumerate() {
            assert_eq!(tree.get(node_id).unwrap().data(), &data[index]);
        }

        let children_ids = tree.children_ids(&node_2).unwrap();
        assert_eq!(children_ids.count(), 0);

        let children_ids = tree.children_ids(&node_3).unwrap();
        assert_eq!(children_ids.count(), 0);
    }
}
<|endoftext|>


<commit_before>use std::result::*;
use std::rc::*;

use rustc_serialize::*;

use super::treenode::*;
use super::basictree::*;
use super::values::*;

///
/// Encoder that will write to the specified tree node
///
struct TreeNodeEncoder {
    tag:    String,
    value:  TreeValue,
    child:  Option<Rc<TreeNode>>
}

impl TreeNodeEncoder {
    fn new() -> TreeNodeEncoder {
        TreeNodeEncoder {
            tag:    "".to_string(),
            value:  TreeValue::Nothing,
            child:  None }
    }

    fn to_basic_tree_node(&self) -> BasicTree {
        let new_node = BasicTree::new(&*self.tag, self.value.to_owned());

        self.child.to_owned().and_then(|child| {
            new_node.set_child_ref(child);
            Some(())
        });

        new_node
    }
}

pub enum TreeNodeCodingError {
    UnsupportedType
}

impl Encoder for TreeNodeEncoder {
    type Error = TreeNodeCodingError;

    fn emit_nil(&mut self) -> Result<(), Self::Error> {
        self.value = TreeValue::Nothing;
        Ok(())
    }

    fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v);
        Ok(())
    }

    fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v as i32);
        Ok(())
    }

    fn emit_i8(&mut self, v: i8) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v as i32);
        Ok(())
    }

    fn emit_bool(&mut self, v: bool) -> Result<(), Self::Error> {
        self.value = TreeValue::Bool(v);
        Ok(())
    }

    fn emit_f64(&mut self, v: f64) -> Result<(), Self::Error> {
        self.value = TreeValue::Real(v);
        Ok(())
    }

    fn emit_f32(&mut self, v: f32) -> Result<(), Self::Error> {
        self.value = TreeValue::Real(v as f64);
        Ok(())
    }

    fn emit_str(&mut self, v: &str) -> Result<(), Self::Error> {
        self.value = TreeValue::String(v.to_string());
        Ok(())
    }

    fn emit_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        self.value = TreeValue::String(name.to_string());

        f(self)
    }

    fn emit_struct_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        // Encode the function into a new encoder
        let mut node_encoder = TreeNodeEncoder::new();
        let encoding_result = f(&mut node_encoder);

        // Short-circuit on error
        if encoding_result.is_err() {
            return encoding_result;
        }

        // Replace the child node with the node generated for the new encoder
        let new_node = node_encoder.to_basic_tree_node();

        self.child.to_owned().and_then(|sibling| {
            new_node.set_sibling_ref(sibling);
            Some(())
        });

        // Save the node we just created and update the tree
        self.child = Some(Rc::new(new_node));

        Ok(())
    }

    fn emit_usize(&mut self, v: usize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u32(&mut self, v: u32) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u16(&mut self, v: u16) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u8(&mut self, v: u8) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_isize(&mut self, v: isize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_i64(&mut self, v: i64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_char(&mut self, v: char) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum<F>(&mut self, name: &str, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_variant_arg<F>(&mut self, a_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_struct_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_struct_variant_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_struct_arg<F>(&mut self, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option<F>(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option_none(&mut self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option_some<F>(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_seq<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_seq_elt<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map_elt_key<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map_elt_val<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }
}
<commit_msg>Add an encode() method and a way to make arbitrary types support ToTreeNode if they're encodable (we don't support it on everything as we already have different to_tree_node() methods for some encodable types)<commit_after>use std::result::*;
use std::rc::*;

use rustc_serialize::*;

use super::treenode::*;
use super::basictree::*;
use super::values::*;

///
/// Encoder that will write to the specified tree node
///
struct TreeNodeEncoder {
    tag:    String,
    value:  TreeValue,
    child:  Option<Rc<TreeNode>>
}

impl TreeNodeEncoder {
    fn new() -> TreeNodeEncoder {
        TreeNodeEncoder {
            tag:    "".to_string(),
            value:  TreeValue::Nothing,
            child:  None }
    }

    fn to_basic_tree_node(&self) -> BasicTree {
        let new_node = BasicTree::new(&*self.tag, self.value.to_owned());

        self.child.to_owned().and_then(|child| {
            new_node.set_child_ref(child);
            Some(())
        });

        new_node
    }
}

pub enum TreeNodeCodingError {
    UnsupportedType
}

impl Encoder for TreeNodeEncoder {
    type Error = TreeNodeCodingError;

    fn emit_nil(&mut self) -> Result<(), Self::Error> {
        self.value = TreeValue::Nothing;
        Ok(())
    }

    fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v);
        Ok(())
    }

    fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v as i32);
        Ok(())
    }

    fn emit_i8(&mut self, v: i8) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v as i32);
        Ok(())
    }

    fn emit_bool(&mut self, v: bool) -> Result<(), Self::Error> {
        self.value = TreeValue::Bool(v);
        Ok(())
    }

    fn emit_f64(&mut self, v: f64) -> Result<(), Self::Error> {
        self.value = TreeValue::Real(v);
        Ok(())
    }

    fn emit_f32(&mut self, v: f32) -> Result<(), Self::Error> {
        self.value = TreeValue::Real(v as f64);
        Ok(())
    }

    fn emit_str(&mut self, v: &str) -> Result<(), Self::Error> {
        self.value = TreeValue::String(v.to_string());
        Ok(())
    }

    fn emit_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        self.value = TreeValue::String(name.to_string());

        f(self)
    }

    fn emit_struct_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        // Encode the function into a new encoder
        let mut node_encoder = TreeNodeEncoder::new();
        let encoding_result = f(&mut node_encoder);

        // Short-circuit on error
        if encoding_result.is_err() {
            return encoding_result;
        }

        // Replace the child node with the node generated for the new encoder
        let new_node = node_encoder.to_basic_tree_node();

        self.child.to_owned().and_then(|sibling| {
            new_node.set_sibling_ref(sibling);
            Some(())
        });

        // Save the node we just created and update the tree
        self.child = Some(Rc::new(new_node));

        Ok(())
    }

    fn emit_usize(&mut self, v: usize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u32(&mut self, v: u32) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u16(&mut self, v: u16) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u8(&mut self, v: u8) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_isize(&mut self, v: isize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_i64(&mut self, v: i64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_char(&mut self, v: char) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum<F>(&mut self, name: &str, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_variant_arg<F>(&mut self, a_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_struct_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_struct_variant_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_struct_arg<F>(&mut self, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option<F>(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option_none(&mut self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option_some<F>(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_seq<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_seq_elt<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map_elt_key<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map_elt_val<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }
}

///
/// Converts an encodable object into a treenode
///
pub fn encode<T: Encodable>(source: &T) -> Rc<TreeNode> {
    // The encoder doesn't directly create a TreeNode because of the way rust lifetimes work
    // (We'd need a <'a> lifetime on the encoder, and that lifetime would prevent recursion by generating
    // new encoders. This is really a limitation of Rust; we work around it by generating the description of
    // a tree node in the encoder and then the tree node itself outside of it)
    //
    // We don't expose the actual encoder publically for this reason, the API is too dumb by necessity.
    let mut encoder = TreeNodeEncoder::new();
    source.encode(&mut encoder);

    Rc::new(encoder.to_basic_tree_node())
}

///
/// Marker trait that can be added to types to make them support encoding to a tree node via .to_tree_node()
///
pub trait EncodeToTreeNode {
    // Empty, this is a marker type
}

impl<T: Encodable + EncodeToTreeNode> ToTreeNode for T {
    ///
    /// Converts this value into a tree node
    ///
    fn to_tree_node(&self) -> Rc<TreeNode> {
        encode(self)
    }
}
<|endoftext|>


<commit_before>//
//     4 -------- 3
//     /₂\²     ¹/²\
//    /   \ [1] /   \
//   / [0] \   / [2] \
//  /₀     ₁\₀/₀     ₁\
// 0 ------- 1 ------- 2
//
//            ┌         ┐
//            | a⁰      |
//            | a¹      |
// global_a = | a² + a³ |
//            | a⁴      |
//            | a⁵      |
//            └         ┘
<commit_msg>Fix comments in assembler.rs<commit_after>//
//     4 -------- 3
//     /₂\²     ¹/²\
//    /   \ [1] /   \
//   / [0] \   / [2] \
//  /₀     ₁\₀/₀     ₁\
// 0 ------- 1 ------- 2
//
//     ┌                 ┐
//     | F0⁰             | 0
//     | F0¹ + F1⁰ + F2⁰ | 1
// F = |             F2¹ | 2
//     |       F1¹ + F2² | 3
//     | F0² + F1²       | 4
//     └                 ┘
<|endoftext|>