<commit_before>//! Visitor for a run-time value with a given layout: Traverse enums, structs and other compound
//! types until we arrive at the leaves, with custom handling for primitive types.

use std::fmt;

use rustc::ty::layout::{self, TyLayout};
use rustc::ty;
use rustc::mir::interpret::{
    EvalResult,
};

use super::{
    Machine, EvalContext, MPlaceTy, PlaceTy, OpTy,
};

// A thing that we can project into, and that has a layout.
// This wouldn't have to depend on `Machine` but with the current type inference,
// that's just more convenient to work with (avoids repeading all the `Machine` bounds).
pub trait Value<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: Copy
{
    // Get this value's layout.
    fn layout(&self) -> TyLayout<'tcx>;

    // Make this a `MPlaceTy`, or panic if that's not possible.
    fn force_allocation(
        self,
        ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
    ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>>;

    // Create this from an `MPlaceTy`.
    fn from_mem_place(MPlaceTy<'tcx, M::PointerTag>) -> Self;

    // Project to the n-th field.
    fn project_field(
        self,
        ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
        field: u64,
    ) -> EvalResult<'tcx, Self>;
}

// Operands and places are both values
impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
    for OpTy<'tcx, M::PointerTag>
{
    #[inline(always)]
    fn layout(&self) -> TyLayout<'tcx> {
        self.layout
    }

    #[inline(always)]
    fn force_allocation(
        self,
        _ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
    ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
        Ok(self.to_mem_place())
    }

    #[inline(always)]
    fn from_mem_place(mplace: MPlaceTy<'tcx, M::PointerTag>) -> Self {
        mplace.into()
    }

    #[inline(always)]
    fn project_field(
        self,
        ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
        field: u64,
    ) -> EvalResult<'tcx, Self> {
        ectx.operand_field(self, field)
    }
}
impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
    for MPlaceTy<'tcx, M::PointerTag>
{
    #[inline(always)]
    fn layout(&self) -> TyLayout<'tcx> {
        self.layout
    }

    #[inline(always)]
    fn force_allocation(
        self,
        _ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
    ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
        Ok(self)
    }

    #[inline(always)]
    fn from_mem_place(mplace: MPlaceTy<'tcx, M::PointerTag>) -> Self {
        mplace
    }

    #[inline(always)]
    fn project_field(
        self,
        ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
        field: u64,
    ) -> EvalResult<'tcx, Self> {
        ectx.mplace_field(self, field)
    }
}
impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
    for PlaceTy<'tcx, M::PointerTag>
{
    #[inline(always)]
    fn layout(&self) -> TyLayout<'tcx> {
        self.layout
    }

    #[inline(always)]
    fn force_allocation(
        self,
        ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
    ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
        ectx.force_allocation(self)
    }

    #[inline(always)]
    fn from_mem_place(mplace: MPlaceTy<'tcx, M::PointerTag>) -> Self {
        mplace.into()
    }

    #[inline(always)]
    fn project_field(
        self,
        ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
        field: u64,
    ) -> EvalResult<'tcx, Self> {
        ectx.place_field(self, field)
    }
}

// How to traverse a value and what to do when we are at the leaves.
pub trait ValueVisitor<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: fmt::Debug + Sized {
    type V: Value<'a, 'mir, 'tcx, M>;

    // There's a value in here.
    fn value(&self) -> &Self::V;

    // The value's layout (not meant to be overwritten).
    #[inline(always)]
    fn layout(&self) -> TyLayout<'tcx> {
        self.value().layout()
    }

    // Replace the value by `val`, which must be the `field`th field of `self`, then call
    // `visit_value` and then un-do everything that might have happened to the visitor state.
    // The point of this is that some visitors keep a stack of fields that we projected below,
    // and this lets us avoid copying that stack; instead they will pop the stack after
    // executing `visit_value`.
    fn visit_field(
        &mut self,
        ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
        val: Self::V,
        field: usize,
    ) -> EvalResult<'tcx>;

    // This is an enum, downcast it to whatever the current variant is.
    // (We do this here and not in `Value` to keep error handling
    // under control of th visitor.)
    fn downcast_enum(&mut self, ectx: &EvalContext<'a, 'mir, 'tcx, M>)
        -> EvalResult<'tcx>;

    // A chance for the visitor to do special (different or more efficient) handling for some
    // array types.  Return `true` if the value was handled and we should return.
    #[inline]
    fn handle_array(&mut self, _ectx: &EvalContext<'a, 'mir, 'tcx, M>)
        -> EvalResult<'tcx, bool>
    {
        Ok(false)
    }

    // Execute visitor on the current value.  Used for recursing.
    #[inline]
    fn visit(&mut self, ectx: &mut EvalContext<'a, 'mir, 'tcx, M>)
        -> EvalResult<'tcx>
    {
        ectx.walk_value(self)
    }

    // Actions on the leaves.
    fn visit_uninhabited(&mut self, ectx: &mut EvalContext<'a, 'mir, 'tcx, M>)
        -> EvalResult<'tcx>;
    fn visit_scalar(&mut self, ectx: &mut EvalContext<'a, 'mir, 'tcx, M>, layout: &layout::Scalar)
        -> EvalResult<'tcx>;
    fn visit_primitive(&mut self, ectx: &mut EvalContext<'a, 'mir, 'tcx, M>)
        -> EvalResult<'tcx>;
}

impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
    pub fn walk_value<V: ValueVisitor<'a, 'mir, 'tcx, M>>(
        &mut self,
        v: &mut V,
    ) -> EvalResult<'tcx> {
        trace!("walk_value: {:?}", v);

        // If this is a multi-variant layout, we have find the right one and proceed with that.
        // (No benefit from making this recursion, but it is equivalent to that.)
        match v.layout().variants {
            layout::Variants::NicheFilling { .. } |
            layout::Variants::Tagged { .. } => {
                v.downcast_enum(self)?;
                trace!("variant layout: {:#?}", v.layout());
            }
            layout::Variants::Single { .. } => {}
        }

        // Even for single variants, we might be able to get a more refined type:
        // If it is a trait object, switch to the actual type that was used to create it.
        match v.layout().ty.sty {
            ty::Dynamic(..) => {
                // immediate trait objects are not a thing
                let dest = v.value().force_allocation(self)?;
                let inner = self.unpack_dyn_trait(dest)?.1;
                // recurse with the inner type
                return v.visit_field(self, Value::from_mem_place(inner), 0);
            },
            _ => {},
        };

        // If this is a scalar, visit it as such.
        // Things can be aggregates and have scalar layout at the same time, and that
        // is very relevant for `NonNull` and similar structs: We need to visit them
        // at their scalar layout *before* descending into their fields.
        // FIXME: We could avoid some redundant checks here. For newtypes wrapping
        // scalars, we do the same check on every "level" (e.g. first we check
        // MyNewtype and then the scalar in there).
        match v.layout().abi {
            layout::Abi::Uninhabited => {
                v.visit_uninhabited(self)?;
            }
            layout::Abi::Scalar(ref layout) => {
                v.visit_scalar(self, layout)?;
            }
            // FIXME: Should we do something for ScalarPair? Vector?
            _ => {}
        }

        // Check primitive types.  We do this after checking the scalar layout,
        // just to have that done as well.  Primitives can have varying layout,
        // so we check them separately and before aggregate handling.
        // It is CRITICAL that we get this check right, or we might be
        // validating the wrong thing!
        let primitive = match v.layout().fields {
            // Primitives appear as Union with 0 fields -- except for Boxes and fat pointers.
            layout::FieldPlacement::Union(0) => true,
            _ => v.layout().ty.builtin_deref(true).is_some(),
        };
        if primitive {
            return v.visit_primitive(self);
        }

        // Proceed into the fields.
        match v.layout().fields {
            layout::FieldPlacement::Union(fields) => {
                // Empty unions are not accepted by rustc. That's great, it means we can
                // use that as an unambiguous signal for detecting primitives.  Make sure
                // we did not miss any primitive.
                debug_assert!(fields > 0);
                // We can't traverse unions, their bits are allowed to be anything.
                // The fields don't need to correspond to any bit pattern of the union's fields.
                // See https://github.com/rust-lang/rust/issues/32836#issuecomment-406875389
            },
            layout::FieldPlacement::Arbitrary { ref offsets, .. } => {
                for i in 0..offsets.len() {
                    let val = v.value().project_field(self, i as u64)?;
                    v.visit_field(self, val, i)?;
                }
            },
            layout::FieldPlacement::Array { .. } => {
                if !v.handle_array(self)? {
                    // We still have to work!
                    // Let's get an mplace first.
                    let mplace = if v.layout().is_zst() {
                        // it's a ZST, the memory content cannot matter
                        MPlaceTy::dangling(v.layout(), self)
                    } else {
                        // non-ZST array/slice/str cannot be immediate
                        v.value().force_allocation(self)?
                    };
                    // Now iterate over it.
                    for (i, field) in self.mplace_array_fields(mplace)?.enumerate() {
                        v.visit_field(self, Value::from_mem_place(field?), i)?;
                    }
                }
            }
        }
        Ok(())
    }
}
<commit_msg>provide some default implementations<commit_after>//! Visitor for a run-time value with a given layout: Traverse enums, structs and other compound
//! types until we arrive at the leaves, with custom handling for primitive types.

use std::fmt;

use rustc::ty::layout::{self, TyLayout};
use rustc::ty;
use rustc::mir::interpret::{
    EvalResult,
};

use super::{
    Machine, EvalContext, MPlaceTy, PlaceTy, OpTy,
};

// A thing that we can project into, and that has a layout.
// This wouldn't have to depend on `Machine` but with the current type inference,
// that's just more convenient to work with (avoids repeading all the `Machine` bounds).
pub trait Value<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: Copy
{
    // Get this value's layout.
    fn layout(&self) -> TyLayout<'tcx>;

    // Make this a `MPlaceTy`, or panic if that's not possible.
    fn force_allocation(
        self,
        ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
    ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>>;

    // Create this from an `MPlaceTy`.
    fn from_mem_place(MPlaceTy<'tcx, M::PointerTag>) -> Self;

    // Project to the n-th field.
    fn project_field(
        self,
        ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
        field: u64,
    ) -> EvalResult<'tcx, Self>;
}

// Operands and places are both values
impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
    for OpTy<'tcx, M::PointerTag>
{
    #[inline(always)]
    fn layout(&self) -> TyLayout<'tcx> {
        self.layout
    }

    #[inline(always)]
    fn force_allocation(
        self,
        _ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
    ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
        Ok(self.to_mem_place())
    }

    #[inline(always)]
    fn from_mem_place(mplace: MPlaceTy<'tcx, M::PointerTag>) -> Self {
        mplace.into()
    }

    #[inline(always)]
    fn project_field(
        self,
        ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
        field: u64,
    ) -> EvalResult<'tcx, Self> {
        ectx.operand_field(self, field)
    }
}
impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
    for MPlaceTy<'tcx, M::PointerTag>
{
    #[inline(always)]
    fn layout(&self) -> TyLayout<'tcx> {
        self.layout
    }

    #[inline(always)]
    fn force_allocation(
        self,
        _ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
    ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
        Ok(self)
    }

    #[inline(always)]
    fn from_mem_place(mplace: MPlaceTy<'tcx, M::PointerTag>) -> Self {
        mplace
    }

    #[inline(always)]
    fn project_field(
        self,
        ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
        field: u64,
    ) -> EvalResult<'tcx, Self> {
        ectx.mplace_field(self, field)
    }
}
impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
    for PlaceTy<'tcx, M::PointerTag>
{
    #[inline(always)]
    fn layout(&self) -> TyLayout<'tcx> {
        self.layout
    }

    #[inline(always)]
    fn force_allocation(
        self,
        ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
    ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
        ectx.force_allocation(self)
    }

    #[inline(always)]
    fn from_mem_place(mplace: MPlaceTy<'tcx, M::PointerTag>) -> Self {
        mplace.into()
    }

    #[inline(always)]
    fn project_field(
        self,
        ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
        field: u64,
    ) -> EvalResult<'tcx, Self> {
        ectx.place_field(self, field)
    }
}

// How to traverse a value and what to do when we are at the leaves.
pub trait ValueVisitor<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: fmt::Debug + Sized {
    type V: Value<'a, 'mir, 'tcx, M>;

    // There's a value in here.
    fn value(&self) -> &Self::V;

    // The value's layout (not meant to be overwritten).
    #[inline(always)]
    fn layout(&self) -> TyLayout<'tcx> {
        self.value().layout()
    }

    // Replace the value by `val`, which must be the `field`th field of `self`, then call
    // `visit_value` and then un-do everything that might have happened to the visitor state.
    // The point of this is that some visitors keep a stack of fields that we projected below,
    // and this lets us avoid copying that stack; instead they will pop the stack after
    // executing `visit_value`.
    fn visit_field(
        &mut self,
        ectx: &mut EvalContext<'a, 'mir, 'tcx, M>,
        val: Self::V,
        field: usize,
    ) -> EvalResult<'tcx>;

    // This is an enum, downcast it to whatever the current variant is.
    // (We do this here and not in `Value` to keep error handling
    // under control of th visitor.)
    fn downcast_enum(&mut self, ectx: &EvalContext<'a, 'mir, 'tcx, M>)
        -> EvalResult<'tcx>;

    // A chance for the visitor to do special (different or more efficient) handling for some
    // array types.  Return `true` if the value was handled and we should return.
    #[inline]
    fn handle_array(&mut self, _ectx: &EvalContext<'a, 'mir, 'tcx, M>)
        -> EvalResult<'tcx, bool>
    {
        Ok(false)
    }

    // Execute visitor on the current value.  Used for recursing.
    #[inline]
    fn visit(&mut self, ectx: &mut EvalContext<'a, 'mir, 'tcx, M>)
        -> EvalResult<'tcx>
    {
        ectx.walk_value(self)
    }

    // Actions on the leaves.
    fn visit_uninhabited(&mut self, _ectx: &mut EvalContext<'a, 'mir, 'tcx, M>)
        -> EvalResult<'tcx>
    { Ok(()) }
    fn visit_scalar(&mut self, _ectx: &mut EvalContext<'a, 'mir, 'tcx, M>, _layout: &layout::Scalar)
        -> EvalResult<'tcx>
    { Ok(()) }
    fn visit_primitive(&mut self, _ectx: &mut EvalContext<'a, 'mir, 'tcx, M>)
        -> EvalResult<'tcx>
    { Ok(()) }
}

impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
    pub fn walk_value<V: ValueVisitor<'a, 'mir, 'tcx, M>>(
        &mut self,
        v: &mut V,
    ) -> EvalResult<'tcx> {
        trace!("walk_value: {:?}", v);

        // If this is a multi-variant layout, we have find the right one and proceed with that.
        // (No benefit from making this recursion, but it is equivalent to that.)
        match v.layout().variants {
            layout::Variants::NicheFilling { .. } |
            layout::Variants::Tagged { .. } => {
                v.downcast_enum(self)?;
                trace!("variant layout: {:#?}", v.layout());
            }
            layout::Variants::Single { .. } => {}
        }

        // Even for single variants, we might be able to get a more refined type:
        // If it is a trait object, switch to the actual type that was used to create it.
        match v.layout().ty.sty {
            ty::Dynamic(..) => {
                // immediate trait objects are not a thing
                let dest = v.value().force_allocation(self)?;
                let inner = self.unpack_dyn_trait(dest)?.1;
                // recurse with the inner type
                return v.visit_field(self, Value::from_mem_place(inner), 0);
            },
            _ => {},
        };

        // If this is a scalar, visit it as such.
        // Things can be aggregates and have scalar layout at the same time, and that
        // is very relevant for `NonNull` and similar structs: We need to visit them
        // at their scalar layout *before* descending into their fields.
        // FIXME: We could avoid some redundant checks here. For newtypes wrapping
        // scalars, we do the same check on every "level" (e.g. first we check
        // MyNewtype and then the scalar in there).
        match v.layout().abi {
            layout::Abi::Uninhabited => {
                v.visit_uninhabited(self)?;
            }
            layout::Abi::Scalar(ref layout) => {
                v.visit_scalar(self, layout)?;
            }
            // FIXME: Should we do something for ScalarPair? Vector?
            _ => {}
        }

        // Check primitive types.  We do this after checking the scalar layout,
        // just to have that done as well.  Primitives can have varying layout,
        // so we check them separately and before aggregate handling.
        // It is CRITICAL that we get this check right, or we might be
        // validating the wrong thing!
        let primitive = match v.layout().fields {
            // Primitives appear as Union with 0 fields -- except for Boxes and fat pointers.
            layout::FieldPlacement::Union(0) => true,
            _ => v.layout().ty.builtin_deref(true).is_some(),
        };
        if primitive {
            return v.visit_primitive(self);
        }

        // Proceed into the fields.
        match v.layout().fields {
            layout::FieldPlacement::Union(fields) => {
                // Empty unions are not accepted by rustc. That's great, it means we can
                // use that as an unambiguous signal for detecting primitives.  Make sure
                // we did not miss any primitive.
                debug_assert!(fields > 0);
                // We can't traverse unions, their bits are allowed to be anything.
                // The fields don't need to correspond to any bit pattern of the union's fields.
                // See https://github.com/rust-lang/rust/issues/32836#issuecomment-406875389
            },
            layout::FieldPlacement::Arbitrary { ref offsets, .. } => {
                for i in 0..offsets.len() {
                    let val = v.value().project_field(self, i as u64)?;
                    v.visit_field(self, val, i)?;
                }
            },
            layout::FieldPlacement::Array { .. } => {
                if !v.handle_array(self)? {
                    // We still have to work!
                    // Let's get an mplace first.
                    let mplace = if v.layout().is_zst() {
                        // it's a ZST, the memory content cannot matter
                        MPlaceTy::dangling(v.layout(), self)
                    } else {
                        // non-ZST array/slice/str cannot be immediate
                        v.value().force_allocation(self)?
                    };
                    // Now iterate over it.
                    for (i, field) in self.mplace_array_fields(mplace)?.enumerate() {
                        v.visit_field(self, Value::from_mem_place(field?), i)?;
                    }
                }
            }
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before><commit_msg>Experiment with new approach to the macro<commit_after>/**
  rest={ <next> ...rest }
  init={}
*/

#[macro_export]
macro_rules! assert_valid_self_arg {
    (self) => {}
}

#[macro_export]
macro_rules! declare_types {
    { $($rest:tt)* } => {
        declare_types_internal! {
            state: top_level,
            program: {
                rest: { $($rest)* },
                init: {}
            }
        }
    }
}

#[doc(hidden)]
#[macro_export]
macro_rules! declare_types_internal {
    // STATE: top_level

    {
        state: top_level,
        program: {
            rest: { },
            init: $init: tt
        }
    } => {
        println!("DONE {}", stringify!($init));
    };

    {
        state: top_level,
        program: $program:tt
    } => {
        declare_types_internal! {
            state: parse_class,
            pub: false,
            reopen: false,
            program: $program
        }
    };

    // STATE: parse_class

    {
        state: parse_class,
        pub: false,
        reopen: false,
        program: {
          rest: { pub $($rest:tt)* },
          init: $init:tt
        }
    } => {
        declare_types_internal! {
            state: parse_class,
            pub: true,
            reopen: false,
            program: {
              rest: { $($rest)* },
              init: $init
            }
        }
    };

    {
        state: parse_class,
        pub: $pub:tt,
        reopen: false,
        program: {
          rest: { reopen $($rest:tt)* },
          init: $init:tt
        }
    } => {
        declare_types_internal! {
            state: parse_class,
            pub: $pub,
            reopen: true,
            program: {
              rest: { $($rest)* },
              init: $init
            }
        }
    };

    {
        state: parse_class,
        pub: $pub:tt,
        reopen: $reopen:tt,
        program: {
          rest: { class $name:ident { $($body:tt)* } $($rest:tt)* },
          init: $init:tt
        }
    } => {
        declare_types_internal! {
            state: class,
            class: {
                meta: { pub: $pub, reopen: $reopen, name: $name },
                body: { $($body)* }
            },
            program: {
              rest: { $($rest)* },
              init: $init
            }
        }
    };

    // STATE: class

    {
        state: class,
        class: {
            meta: $meta:tt,
            body: { def $($rest:tt)* }
        },
        program: $program:tt
    } => {
        declare_types_internal! {
            state: parse_method,
            class: {
                meta: $meta,
                body: { $($rest)* }
            },
            program: $program
        }
    };

    {
        state: class,
        class: {
            meta: $meta:tt,
            body: { struct $($rest:tt)* }
        },
        program: $program:tt
    } => {
        declare_types_internal! {
            state: parse_struct,
            class: {
                meta: $meta,
                body: { $($rest)* }
            },
            program: $program
        }
    };

    {
        state: class,
        class: {
            meta: $meta:tt,
            body: { }
        },
        program: $program:tt
    } => {
        println!("{}", stringify!(class: {
            meta: $meta
        }));

        declare_types_internal! {
            state: top_level,
            program: $program
        }
    };

    // STATE: parse_method

    {
        state: parse_method,
        class: {
            meta: $meta:tt,
            body: { initialize $($rest:tt)* }
        },
        program: $program:tt
    } => {
        declare_types_internal! {
            state: parse_initialize,
            class: {
                meta: $meta,
                body: { $($rest)* }
            },
            method: {
                type: initializer,
                name: initialize,
            },
            program: $program
        }
    };

    {
        state: parse_method,
        class: {
            meta: $meta:tt,
            body: { $name:ident ( $($args:tt)* ) $($rest:tt)* }
        },
        program: $program:tt
    } => {
        declare_types_internal! {
            state: parse_arguments_self,
            class: {
                meta: $meta,
                body: { $($rest)* }
            },
            method: {
                name: $name,
            },
            args: { $($args)* },
            program: $program
        }
    };

    // STATE: parse_arguments_self

    {
        state: parse_arguments_self,
        class: $class:tt,
        method: {
            name: $name:tt,
        },
        args: { & mut $self_arg:ident $($rest:tt)* },
        program: $program:tt
    } => {
        assert_valid_self_arg!($self_arg);

        declare_types_internal! {
            state: parse_arguments_consume_possible_comma,
            class: $class,
            method: {
                type: instance,
                name: $name,
                self: {
                    ownership: { & mut },
                    name: $self_arg
                }
            },
            args: { $($rest)* },
            program: $program
        }
    };

    {
        state: parse_arguments_self,
        class: $class:tt,
        method: {
            name: $name:tt,
        },
        args: { & $self_arg:ident $($rest:tt)* },
        program: $program:tt
    } => {
        assert_valid_self_arg!($self_arg);

        declare_types_internal! {
            state: parse_arguments_consume_possible_comma,
            class: $class,
            method: {
                type: instance,
                name: $name,
                self: {
                    ownership: { & },
                    name: $self_arg
                }
            },
            args: { $($rest)* },
            program: $program
        }
    };

    {
        state: parse_arguments_self,
        class: $class:tt,
        method: {
            name: $name:tt,
        },
        args: { $($rest:tt)* },
        program: $program:tt
    } => {
        declare_types_internal! {
            state: parse_arguments,
            class: $class,
            method: {
                type: class,
                name: $name,
                self: ()
            },
            args: { $($rest)* },
            program: $program
        }
    };

    // STATE: parse_arguments_consume_possible_comma

    {
        state: parse_arguments_consume_possible_comma,
        class: $class:tt,
        method: $method:tt,
        args: { , $($rest:tt)+ },
        program: $program:tt
    } => {
        declare_types_internal! {
            state: parse_arguments,
            class: $class,
            method: $method,
            args: { $($rest)+ },
            program: $program
        }
    };

    {
        state: parse_arguments_consume_possible_comma,
        class: $class:tt,
        method: $method:tt,
        args: { },
        program: $program:tt
    } => {
        declare_types_internal! {
            state: parse_arguments,
            class: $class,
            method: $method,
            args: { },
            program: $program
        }
    };

    // STATE: parse_arguments

    {
        state: parse_arguments,
        class: $class:tt,
        method: {
            type: $type:ident,
            name: $name:tt,
            self: $self:tt
        },
        args: { $($args:tt)* },
        program: $program:tt
    } => {
        declare_types_internal! {
            state: parse_return_type,
            class: $class,
            method: {
                type: $type,
                name: $name,
                self: $self,
                args: { $($args)* }
            },
            program: $program
        }
    };

    // STATE: parse_return_type

    {
        state: parse_return_type,
        class: {
            meta: $meta:tt,
            body: { -> $ret:ty $body:block $($rest:tt)* }
        },
        method: {
            type: $type:ident,
            name: $name:tt,
            self: $self:tt,
            args: $args:tt
        },
        program: $program:tt
    } => {
        println!("{}", stringify!(method: {
            type: $type,
            name: $name,
            self: $self,
            args: $args,
            ret: $ret
        }));

        declare_types_internal! {
            state: class,
            class: {
                meta: $meta,
                body: { $($rest)* }
            },
            program: $program
        }
    };

    {
        state: parse_return_type,
        class: {
            meta: $meta:tt,
            body: { $body:block $($rest:tt)* }
        },
        method: {
            type: $type:ident,
            name: $name:tt,
            self: $self:tt,
            args: $args:tt
        },
        program: $program:tt
    } => {
        println!("{}", stringify!(method: {
            type: $type,
            name: $name,
            self: $self,
            args: $args,
            ret: ()
        }));

        declare_types_internal! {
            state: class,
            class: {
                meta: $meta,
                body: { $($rest)* }
            },
            program: $program
        }
    };

    // // STATE: class_signature

    // {
    //     state: class_signature,
    //     class_tokens: { }
    //     program: {
    //         rest: {
    //             $($signature:ident)* class $name:ident { $($body:tt)* }
    //             $($rest:tt)*
    //         },
    //         init: $init:tt
    //     }
    // } => {
    //     declare_types_internal! {
    //         class_signature: {
    //           rest: { $($signature)* },
    //           body: { $(body)* },
    //           accum: { pub: false, reopen: false }
    //         },
    //         accum: { rest: { $($rest)* }, init: $init }
    //     }
    // };

    // // Step 2: parse the class signature

    // {
    //     class_signature: {
    //         rest: { pub $($rest:ident)* },
    //         body: $body:tt,
    //         accum: { pub: $pub:tt, reopen: false }
    //     },
    //     accum: $accum:tt
    // } => {
    //     declare_types_internal! {
    //         class_signature: {
    //           rest: { $($rest)* },
    //           body: $body,
    //           accum: { pub: true, reopen: false }
    //         },
    //         accum: $accum
    //     }
    // };

    // {
    //     class_signature: {
    //         rest: { reopen $($rest:ident)* },
    //         body: $body:tt,
    //         accum: { pub: $pub:tt, reopen: false }
    //     },
    //     accum: $accum:tt
    // } => {
    //     declare_types_internal! {
    //         class_signature: {
    //           rest: { $($rest)* },
    //           body: $body,
    //           accum: { pub: $pub, reopen: true }
    //         },
    //         accum: $accum
    //     }
    // };

    // {
    //     class_signature: {
    //         rest: { class $name:ident },
    //         body: $body:tt
    //         accum: { pub: $pub:tt, reopen: $reopen:tt }
    //     },
    //     accum: $accum:tt
    // } => {
    //     declare_types_internal! {
    //         class: {
    //           meta: { name: $name, pub: $pub, reopen: $reopen }
    //           rest: { $(body)* },
    //           accum: { }
    //         },
    //         accum: $accum
    //     }
    // };

    // // Step 3: take a method out of rest

    // {
    //     class: {
    //         meta: $meta:tt,
    //         rest: {
    //             def $name:ident($($args:tt)*) $(-> $ret:ty)* { $($body:tt)* }
    //             $($rest:tt)*
    //         },
    //         accum: $class_accum:tt
    //     },
    //     accum: $accum:tt
    // } => {
    //     declare_types_internal! {
    //         method: {
    //             def $name:ident($($args)*) $(-> $ret)* { $($body)* }
    //         },

    //         class: {
    //             meta:     $meta,
    //             rest:     { $($rest)* },
    //             elements: $elements
    //         },

    //         accum: $class_accum
    //     }
    // };

    // { $($all:tt)* } => {
    //     println!("ERROR: {}", stringify!($($all)*));
    // };
}

fn main() {
    declare_types! {
        class Foo {
            def multiply(&self, one: f64, two: f64) -> f64 {
                one * two
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix typo<commit_after><|endoftext|>


<commit_before><commit_msg>Add stats function to get the db statistics<commit_after><|endoftext|>


<commit_before><commit_msg>working joiner<commit_after>use std::os;
use std::str;
use std::io::File;

fn main() {
    let args: ~[~str] = os::args();
    if args.len() != 3 {
        println!("Usage: {:s} <msg.share1> <msg.share2>", args[0]);
    } else {
        let share1 = args[1].clone();
        let share2 = args[2].clone();
        let path1 = Path::new(share1.clone());
        let path2 = Path::new(share2.clone());
        let msg1_file = File::open(&path1);
        let msg2_file = File::open(&path2);

        match (msg1_file, msg2_file) {
            (Some(mut msg1), Some(mut msg2)) => {
                let msg1_bytes: ~[u8] = msg1.read_to_end();
                let msg2_bytes: ~[u8] = msg2.read_to_end();
                let result: ~[u8] = xor(msg1_bytes, msg2_bytes);
                print!("{:?}", str::from_utf8(result));
            } ,
            (None, _ ) => fail!("Error opening message file: {:s}", share1),
            (_ ,None) => fail!("Error opening message file: {:s}", share2)
        }
    }
}

fn xor(a: &[u8], b: &[u8]) -> ~[u8] {
    let mut ret = ~[];
    for i in range(0, a.len()) {
	ret.push(a[i] ^ b[i]);
    }
    ret
}
<|endoftext|>


<commit_before><commit_msg>rururust.<commit_after><|endoftext|>


<commit_before><commit_msg>add excel_to_csv example<commit_after>extern crate office;

use std::env;
use std::fs::File;
use std::io::{BufWriter, Write};
use std::path::PathBuf;
use office::{Excel, Range, DataType, Result};

fn main() {
    // converts first argument into a csv (same name, silently overrides
    // if the file already exists

    let file = env::args().skip(1).next()
        .expect("Please provide an excel file to convert");
    let sheet = env::args().skip(2).next()
        .expect("Expecting a sheet name as second argument");

    let sce = PathBuf::from(file);
    match sce.extension().and_then(|s| s.to_str()) {
        Some("xlsx") | Some("xlsm") | Some("xlsb") => (),
        _ => panic!("Expecting an excel file"),
    }

    let dest = sce.with_extension("csv");
    let mut dest = BufWriter::new(File::create(dest).unwrap());
    let mut xl = Excel::open(&sce).unwrap();
    let range = xl.worksheet_range(&sheet).unwrap();

    write_range(&mut dest, range).unwrap();
}

fn write_range<W: Write>(dest: &mut W, range: Range) -> Result<()> {
    let n = range.get_size().1 - 1;
    for r in range.rows() {
        for (i, c) in r.iter().enumerate() {
            let _ = try!(match *c {
                DataType::Empty => Ok(()),
                DataType::String(ref s) => write!(dest, "{}", s),
                DataType::Float(ref f) => write!(dest, "{}", f),
                DataType::Int(ref i) => write!(dest, "{}", i),
                DataType::Error(ref e) => write!(dest, "{:?}", e),
                DataType::Bool(ref b) => write!(dest, "{}", b),
            });
            if i != n {
                let _ = try!(write!(dest, ";"));
            }
        }
        let _ = try!(write!(dest, "\r\n"));
    }
    Ok(())
}
<|endoftext|>


<commit_before><commit_msg>Use `verify_raw` rather than `verify` to check signatures<commit_after><|endoftext|>


<commit_before><commit_msg>Do not render a zero texture<commit_after><|endoftext|>


<commit_before><commit_msg>solved Shortest Word (7 kyu) in Rust<commit_after><|endoftext|>


<commit_before>#![feature(globs)]

extern crate libc;
extern crate neovim;
extern crate rgtk;
extern crate serialize;

use rgtk::*;
use std::collections::HashSet;
use std::io::fs;
use std::io::fs::PathExtensions;

mod projects;
mod ui;
mod utils;

mod ffi {
    pub use libc::{c_int, c_uchar, c_void};
    pub use libc::funcs::posix88::unistd::{close, pipe, read, write};
    pub use libc::types::os::arch::c95::size_t;

    extern "C" {
        pub fn fork () -> c_int;
        pub fn kill (pid: c_int, sig: c_int);
    }
}

fn gui_main(
    pty: &mut gtk::VtePty,
    read_fd: ffi::c_int,
    write_fd: ffi::c_int,
    pid: ffi::c_int)
{
    gtk::init();

    // constants

    let width = 1242;
    let height = 768;
    let editor_height = ((height as f32) * 0.75) as i32;

    // create the window

    let title = format!("SolidOak {}.{}.{}",
                        option_env!("CARGO_PKG_VERSION_MAJOR").unwrap(),
                        option_env!("CARGO_PKG_VERSION_MINOR").unwrap(),
                        option_env!("CARGO_PKG_VERSION_PATCH").unwrap());
    let mut window = gtk::Window::new(gtk::WindowType::TopLevel).unwrap();
    window.set_title(title.as_slice());
    window.set_window_position(gtk::WindowPosition::Center);
    window.set_default_size(width, height);

    window.connect(gtk::signals::DeleteEvent::new(|_| {
        unsafe {
            ffi::close(read_fd);
            ffi::close(write_fd);
            ffi::kill(pid, 15);
        }
        gtk::main_quit();
        true
    }));

    // create the panes

    let new_button = gtk::Button::new_with_label("New Project").unwrap();
    let import_button = gtk::Button::new_with_label("Import").unwrap();
    let rename_button = gtk::Button::new_with_label("Rename").unwrap();
    let remove_button = gtk::Button::new_with_label("Remove").unwrap();

    let mut project_buttons = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    project_buttons.set_size_request(-1, -1);
    project_buttons.add(&new_button);
    project_buttons.add(&import_button);
    project_buttons.add(&rename_button);
    project_buttons.add(&remove_button);

    let mut project_tree = gtk::TreeView::new().unwrap();
    let selection = project_tree.get_selection().unwrap();
    let column_types = [glib::ffi::g_type_string, glib::ffi::g_type_string];
    let store = gtk::TreeStore::new(&column_types).unwrap();
    let model = store.get_model().unwrap();
    project_tree.set_model(&model);
    project_tree.set_headers_visible(false);

    let mut scroll_pane = gtk::ScrolledWindow::new(None, None).unwrap();
    scroll_pane.add(&project_tree);

    let column = gtk::TreeViewColumn::new().unwrap();
    let cell = gtk::CellRendererText::new().unwrap();
    column.pack_start(&cell, true);
    column.add_attribute(&cell, "text", 0);
    project_tree.append_column(&column);

    let mut project_pane = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    project_pane.set_size_request(-1, -1);
    project_pane.pack_start(&project_buttons, false, true, 0);
    project_pane.pack_start(&scroll_pane, true, true, 0);

    let mut editor_pane = gtk::VteTerminal::new().unwrap();
    editor_pane.set_size_request(-1, editor_height);
    editor_pane.set_pty(pty);
    editor_pane.watch_child(pid);

    let run_button = gtk::Button::new_with_label("Run").unwrap();
    let build_button = gtk::Button::new_with_label("Build").unwrap();
    let test_button = gtk::Button::new_with_label("Test").unwrap();
    let clean_button = gtk::Button::new_with_label("Clean").unwrap();
    let stop_button = gtk::Button::new_with_label("Stop").unwrap();

    let mut build_buttons = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    build_buttons.set_size_request(-1, -1);
    build_buttons.add(&run_button);
    build_buttons.add(&build_button);
    build_buttons.add(&test_button);
    build_buttons.add(&clean_button);
    build_buttons.add(&stop_button);

    let build_term = gtk::VteTerminal::new().unwrap();

    let mut build_pane = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    build_pane.pack_start(&build_buttons, false, true, 0);
    build_pane.pack_start(&build_term, true, true, 0);

    let mut content = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    content.pack_start(&editor_pane, false, true, 0);
    content.pack_start(&build_pane, true, true, 0);

    let mut hbox = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    hbox.pack_start(&project_pane, false, true, 0);
    hbox.pack_start(&content, true, true, 0);
    window.add(&hbox);

    // populate the project tree

    let mut state = ::utils::State{
        projects: HashSet::new(),
        expansions: HashSet::new(),
        selection: None,
        tree_model: &model,
        tree_store: &store,
        tree_selection: &selection,
        rename_button: &rename_button,
        remove_button: &remove_button,
    };

    ::utils::read_prefs(&mut state);
    ::ui::update_project_tree(&mut state, &mut project_tree);

    // connect to the signals

    new_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::new_project(&mut state, &mut project_tree);
    }));
    import_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::import_project(&mut state, &mut project_tree);
    }));
    rename_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::rename_file(&mut state);
    }));
    remove_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::remove_item(&mut state);
    }));
    selection.connect(gtk::signals::Changed::new(|| {
        ::projects::save_selection(&mut state);
    }));
    project_tree.connect(gtk::signals::RowCollapsed::new(|iter_raw, _| {
        let iter = gtk::TreeIter::wrap_pointer(iter_raw);
        ::projects::remove_expansion(&mut state, &iter);
    }));
    project_tree.connect(gtk::signals::RowExpanded::new(|iter_raw, _| {
        let iter = gtk::TreeIter::wrap_pointer(iter_raw);
        ::projects::add_expansion(&mut state, &iter);
    }));

    // show the window

    window.show_all();
    gtk::main();
}

fn main() {
    // create data dir and set $VIM to it
    let path = ::utils::get_data_dir();
    if !path.exists() {
        match fs::mkdir(&path, ::std::io::USER_DIR) {
            Ok(_) => {
                // TODO: copy all the vim files into the path
            },
            Err(e) => { println!("Error creating directory: {}", e) }
        }
    }
    std::os::setenv("VIM", path.as_str().unwrap());

    // takes care of piping stdin/stdout between the gui and nvim
    let mut pty = gtk::VtePty::new().unwrap();

    // two pairs of anonymous pipes for msgpack-rpc between the gui and nvim
    let mut nvim_from_gui : [ffi::c_int, ..2] = [0, ..2];
    let mut gui_from_nvim : [ffi::c_int, ..2] = [0, ..2];
    unsafe {
        ffi::pipe(nvim_from_gui.as_mut_ptr());
        ffi::pipe(gui_from_nvim.as_mut_ptr());
    };

    // split into two processes
    let pid = unsafe { ffi::fork() };

    if pid > 0 { // the gui process
        // listen for messages from nvim
        spawn(proc() {
            let mut buf : [ffi::c_uchar, ..100] = [0, ..100];
            unsafe {
                loop {
                    let buf_ptr = buf.as_mut_ptr() as *mut ffi::c_void;
                    let n = ffi::read(gui_from_nvim[0], buf_ptr, 100);
                    if n < 0 {
                        break;
                    } else if n > 0 {
                        let msg = std::str::from_utf8(buf.slice_to(n as uint)).unwrap();
                        println!("Received: {}", msg);
                    }
                }
            }
        });

        // start the gui
        gui_main(&mut pty, gui_from_nvim[0], gui_from_nvim[1], pid);
    } else { // the nvim process
        // prepare this process to be piped into the gui
        pty.child_setup();

        // listen for messages from the gui
        spawn(proc() {
            std::io::timer::sleep(std::time::Duration::seconds(1));

            let mut ch = neovim::Channel::new_with_fds(nvim_from_gui[0], gui_from_nvim[1]);
            ch.subscribe("test");

            unsafe {
                let msg = "Hello, world!";
                let msg_c = msg.to_c_str();
                let msg_ptr = msg_c.as_ptr() as *const ffi::c_void;
                ffi::write(gui_from_nvim[1], msg_ptr, msg_c.len() as ffi::size_t);
            }
        });

        // start nvim
        neovim::run_with_vec(std::os::args());
    }
}
<commit_msg>Use a callback instead of a thread<commit_after>#![feature(globs)]

extern crate libc;
extern crate neovim;
extern crate rgtk;
extern crate serialize;

use rgtk::*;
use std::collections::HashSet;
use std::io::fs;
use std::io::fs::PathExtensions;

mod projects;
mod ui;
mod utils;

mod ffi {
    pub use libc::{c_int, c_uchar, c_void};
    pub use libc::funcs::posix88::unistd::{close, pipe, read, write};
    pub use libc::types::os::arch::c95::size_t;

    extern "C" {
        pub fn fork () -> c_int;
        pub fn kill (pid: c_int, sig: c_int);
    }
}

fn gui_main(
    pty: &mut gtk::VtePty,
    read_fd: ffi::c_int,
    write_fd: ffi::c_int,
    pid: ffi::c_int)
{
    gtk::init();

    // constants

    let width = 1242;
    let height = 768;
    let editor_height = ((height as f32) * 0.75) as i32;

    // create the window

    let title = format!("SolidOak {}.{}.{}",
                        option_env!("CARGO_PKG_VERSION_MAJOR").unwrap(),
                        option_env!("CARGO_PKG_VERSION_MINOR").unwrap(),
                        option_env!("CARGO_PKG_VERSION_PATCH").unwrap());
    let mut window = gtk::Window::new(gtk::WindowType::TopLevel).unwrap();
    window.set_title(title.as_slice());
    window.set_window_position(gtk::WindowPosition::Center);
    window.set_default_size(width, height);

    window.connect(gtk::signals::DeleteEvent::new(|_| {
        unsafe {
            ffi::close(read_fd);
            ffi::close(write_fd);
            ffi::kill(pid, 15);
        }
        gtk::main_quit();
        true
    }));

    // create the panes

    let new_button = gtk::Button::new_with_label("New Project").unwrap();
    let import_button = gtk::Button::new_with_label("Import").unwrap();
    let rename_button = gtk::Button::new_with_label("Rename").unwrap();
    let remove_button = gtk::Button::new_with_label("Remove").unwrap();

    let mut project_buttons = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    project_buttons.set_size_request(-1, -1);
    project_buttons.add(&new_button);
    project_buttons.add(&import_button);
    project_buttons.add(&rename_button);
    project_buttons.add(&remove_button);

    let mut project_tree = gtk::TreeView::new().unwrap();
    let selection = project_tree.get_selection().unwrap();
    let column_types = [glib::ffi::g_type_string, glib::ffi::g_type_string];
    let store = gtk::TreeStore::new(&column_types).unwrap();
    let model = store.get_model().unwrap();
    project_tree.set_model(&model);
    project_tree.set_headers_visible(false);

    let mut scroll_pane = gtk::ScrolledWindow::new(None, None).unwrap();
    scroll_pane.add(&project_tree);

    let column = gtk::TreeViewColumn::new().unwrap();
    let cell = gtk::CellRendererText::new().unwrap();
    column.pack_start(&cell, true);
    column.add_attribute(&cell, "text", 0);
    project_tree.append_column(&column);

    let mut project_pane = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    project_pane.set_size_request(-1, -1);
    project_pane.pack_start(&project_buttons, false, true, 0);
    project_pane.pack_start(&scroll_pane, true, true, 0);

    let mut editor_pane = gtk::VteTerminal::new().unwrap();
    editor_pane.set_size_request(-1, editor_height);
    editor_pane.set_pty(pty);
    editor_pane.watch_child(pid);

    let run_button = gtk::Button::new_with_label("Run").unwrap();
    let build_button = gtk::Button::new_with_label("Build").unwrap();
    let test_button = gtk::Button::new_with_label("Test").unwrap();
    let clean_button = gtk::Button::new_with_label("Clean").unwrap();
    let stop_button = gtk::Button::new_with_label("Stop").unwrap();

    let mut build_buttons = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    build_buttons.set_size_request(-1, -1);
    build_buttons.add(&run_button);
    build_buttons.add(&build_button);
    build_buttons.add(&test_button);
    build_buttons.add(&clean_button);
    build_buttons.add(&stop_button);

    let build_term = gtk::VteTerminal::new().unwrap();

    let mut build_pane = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    build_pane.pack_start(&build_buttons, false, true, 0);
    build_pane.pack_start(&build_term, true, true, 0);

    let mut content = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    content.pack_start(&editor_pane, false, true, 0);
    content.pack_start(&build_pane, true, true, 0);

    let mut hbox = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    hbox.pack_start(&project_pane, false, true, 0);
    hbox.pack_start(&content, true, true, 0);
    window.add(&hbox);

    // populate the project tree

    let mut state = ::utils::State{
        projects: HashSet::new(),
        expansions: HashSet::new(),
        selection: None,
        tree_model: &model,
        tree_store: &store,
        tree_selection: &selection,
        rename_button: &rename_button,
        remove_button: &remove_button,
    };

    ::utils::read_prefs(&mut state);
    ::ui::update_project_tree(&mut state, &mut project_tree);

    // connect to the signals

    new_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::new_project(&mut state, &mut project_tree);
    }));
    import_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::import_project(&mut state, &mut project_tree);
    }));
    rename_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::rename_file(&mut state);
    }));
    remove_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::remove_item(&mut state);
    }));
    selection.connect(gtk::signals::Changed::new(|| {
        ::projects::save_selection(&mut state);
    }));
    project_tree.connect(gtk::signals::RowCollapsed::new(|iter_raw, _| {
        let iter = gtk::TreeIter::wrap_pointer(iter_raw);
        ::projects::remove_expansion(&mut state, &iter);
    }));
    project_tree.connect(gtk::signals::RowExpanded::new(|iter_raw, _| {
        let iter = gtk::TreeIter::wrap_pointer(iter_raw);
        ::projects::add_expansion(&mut state, &iter);
    }));

    // show the window

    window.show_all();
    gtk::main();
}

extern "C" fn nvim_init(read_fs: i32, write_fs: i32) {
    let mut ch = neovim::Channel::new_with_fds(read_fs, write_fs);
    ch.subscribe("test");

    unsafe {
        let msg = "Hello, world!";
        let msg_c = msg.to_c_str();
        let msg_ptr = msg_c.as_ptr() as *const ffi::c_void;
        ffi::write(write_fs, msg_ptr, msg_c.len() as ffi::size_t);
    }
}

fn main() {
    // create data dir and set $VIM to it
    let path = ::utils::get_data_dir();
    if !path.exists() {
        match fs::mkdir(&path, ::std::io::USER_DIR) {
            Ok(_) => {
                // TODO: copy all the vim files into the path
            },
            Err(e) => { println!("Error creating directory: {}", e) }
        }
    }
    std::os::setenv("VIM", path.as_str().unwrap());

    // takes care of piping stdin/stdout between the gui and nvim
    let mut pty = gtk::VtePty::new().unwrap();

    // two pairs of anonymous pipes for msgpack-rpc between the gui and nvim
    let mut nvim_from_gui : [ffi::c_int, ..2] = [0, ..2];
    let mut gui_from_nvim : [ffi::c_int, ..2] = [0, ..2];
    unsafe {
        ffi::pipe(nvim_from_gui.as_mut_ptr());
        ffi::pipe(gui_from_nvim.as_mut_ptr());
    };

    // split into two processes
    let pid = unsafe { ffi::fork() };

    if pid > 0 { // the gui process
        // listen for messages from nvim
        spawn(proc() {
            let mut buf : [ffi::c_uchar, ..100] = [0, ..100];
            unsafe {
                loop {
                    let buf_ptr = buf.as_mut_ptr() as *mut ffi::c_void;
                    let n = ffi::read(gui_from_nvim[0], buf_ptr, 100);
                    if n < 0 {
                        break;
                    } else if n > 0 {
                        let msg = std::str::from_utf8(buf.slice_to(n as uint)).unwrap();
                        println!("Received: {}", msg);
                    }
                }
            }
        });

        // start the gui
        gui_main(&mut pty, gui_from_nvim[0], gui_from_nvim[1], pid);
    } else { // the nvim process
        // prepare this process to be piped into the gui
        pty.child_setup();

        // start nvim
        neovim::run_with_callback(std::os::args(),
                                  Some(nvim_init),
                                  nvim_from_gui[0],
                                  gui_from_nvim[1]);
    }
}
<|endoftext|>


<commit_before><commit_msg>Operational schedule items.<commit_after><|endoftext|>


<commit_before><commit_msg>Adjust spacing on clap api.<commit_after><|endoftext|>


<commit_before><commit_msg>Refactors main a bit.<commit_after><|endoftext|>


<commit_before><commit_msg>very shady actors<commit_after><|endoftext|>


<commit_before><commit_msg>add unfinished example<commit_after>#[macro_use]
extern crate hsm;
#[macro_use]
extern crate log;
extern crate fern;
extern crate time;

#[derive(Debug, Clone)]
enum Events {
    Plus,
    Minus,
    Int(u32)
}

#[derive(Debug)]
enum Tokens {
    Plus,
    Minus,
    Int(i32)
}

#[derive(Debug)]
struct SharedData {
    accepted_tokens: Vec<Tokens>
}
impl SharedData {
    fn new() -> Self {
        SharedData {accepted_tokens: Vec::new()}
    }
}

hsm_define_objects!(StateStruct, States, Events, SharedData, (
    WaitMinusOrInt {counter: u8 = 0},
    WaitInt {},
    WaitOp {}
));

hsm_state_parents!(States; WaitMinusOrInt -> None, WaitInt -> None, WaitOp -> None );

impl hsm::State<Events, States, SharedData> for WaitMinusOrInt<Events, States, SharedData> {
    fn handle_event(&mut self, shr_data: &mut SharedData, evt: hsm::Event<Events>, probe: bool) -> hsm::Action<States> {
        self.counter += 1;
        info!("{} time in WaitMinusOrInt, shared: {:?}", self.counter, shr_data);
        match evt {
            hsm::Event::User(Events::Minus) => {
                info!("minus");
                hsm::Action::Transition(States::WaitInt)
            },
            hsm::Event::User(Events::Int(x)) => {
                info!("int({:?})", x);
                hsm::Action::Transition(States::WaitOp)
            },
            _ => hsm::Action::Ignore
        }
    }
}

impl hsm::State<Events, States, SharedData> for WaitInt<Events, States, SharedData> {
    fn handle_event(&mut self, shr_data: &mut SharedData, evt: hsm::Event<Events>, probe: bool) -> hsm::Action<States> {
        match evt {
            hsm::Event::User(Events::Int(x)) => hsm_delayed_transition!(probe, {
                info!("int({:?})", x);
                States::WaitOp
            }),
            _ => hsm::Action::Ignore
        }
    }
}

hsm_impl_state!(WaitOp, Events, States, SharedData,
    hsm::Event::User(Events::Minus) => {
        info!("minus");
        hsm::Action::Transition(States::WaitMinusOrInt)
    },
    hsm::Event::User(Events::Plus) => {
        info!("plus");
        hsm::Action::Transition(States::WaitMinusOrInt)
    },
    _ => hsm::Action::Ignore
);

fn main() {
    conf_logger();
    let mut sm = hsm::StateMachine::<StateStruct, States, Events, SharedData>::new(States::WaitMinusOrInt, SharedData::new());
    sm.start();
    sm.input(hsm::Event::User(Events::Int(4)));
    sm.input(hsm::Event::User(Events::Plus));
    sm.input(hsm::Event::User(Events::Minus));
    sm.input(hsm::Event::User(Events::Int(5)));
}

fn conf_logger() {
    let logger_config = fern::DispatchConfig {
        format: Box::new(|msg: &str, level: &log::LogLevel, _location: &log::LogLocation| {
            let t = time::now();
            let ms = t.tm_nsec/1000_000;
            format!("{}.{:3} [{}] {}", t.strftime("%Y-%m-%dT%H:%M:%S").unwrap(), ms, level, msg)
        }),
        output: vec![fern::OutputConfig::stderr()],
        level: log::LogLevelFilter::Trace,
    };

    if let Err(e) = fern::init_global_logger(logger_config, log::LogLevelFilter::Trace) {
        panic!("Failed to initialize global logger: {}", e);
    }
}
<|endoftext|>


<commit_before><commit_msg>Implement the From trait on a wrapper around a vector of bytes for u16 and u32 so we can pack numbers into messages<commit_after><|endoftext|>


<commit_before><commit_msg>Add test for issue #79949<commit_after>// check-pass

#![allow(incomplete_features)]
#![feature(associated_type_bounds)]
#![feature(generic_associated_types)]

trait MP {
    type T<'a>;
}
struct S(String);
impl MP for S {
    type T<'a> = &'a str;
}

trait SR: MP {
    fn sr<IM>(&self) -> i32
    where
        for<'a> IM: T<T: U<<Self as MP>::T<'a>>>;
}

trait T {
    type T;
}
trait U<X> {}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Update main.rs<commit_after><|endoftext|>


<commit_before><commit_msg>removed redundant matches<commit_after><|endoftext|>


<commit_before><commit_msg>parse length prefix<commit_after><|endoftext|>


<commit_before><commit_msg>ruskey: add basic main function<commit_after>use std::error::Error;

fn try_main() -> Result<(), Box<Error>> {
    Ok(())
}

fn main() {
    if let Err(err) = try_main() {
        panic!("{}", err.description());
    }
}
<|endoftext|>


<commit_before><commit_msg>Provide more detail when logging a snapshot start<commit_after><|endoftext|>


<commit_before><commit_msg>Fixed merge artifact<commit_after><|endoftext|>


<commit_before><commit_msg>Fix some compile errors<commit_after><|endoftext|>


<commit_before><commit_msg>Add problem #86<commit_after>use common::calc::{ each_prim_pythagorean };
use common::problem::{ Problem };

pub static problem: Problem<'static> = Problem {
    id: 86,
    answer: "1818",
    solver: solve
};

fn get_count(m: uint) -> uint {
    let mut cnt = 0u;
    for uint::range(0, m) |max_a| {
        for each_prim_pythagorean(max_a) |p, q, _| {
            for uint::range(1, m / q + 1) |k| {
                cnt += k * p / 2;
            }

            for uint::range(1, m / p + 1) |k| {
                let end = uint::min(k * p, k * q / 2) + 1;
                let start = k * q - k * p;
                if end > start { cnt += end - start; }
            }
        }
    }
    return cnt;
}

// cuboid: (a, b, c),  a <= b <= c <= M
// => S = sqrt(c^2 + (a + b)^2)
fn solve() -> ~str {
    let mut limit_cnt = 1000000;

    let mut lim = 1;
    let mut cnt = get_count(lim);
    while cnt < limit_cnt {
        lim *= 2;
        cnt = get_count(lim);
    }

    let mut m = 0;
    while lim != 0 {
        let ix = m + (lim >> 1);
        let cnt = get_count(ix);
        match cnt.cmp(&limit_cnt) {
            Equal => break,
            Less  => {
                m = ix + 1;
                lim -= 1;
            }
            Greater => {}
        }
        lim >>= 1;
    }

    return m.to_str();
}
<|endoftext|>


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

// Regression test for Issue #22536: If a type implements Copy, then
// moving it must not zero the original memory.

trait Resources {
    type Buffer: Copy;
    fn foo(&self) {}
}

struct BufferHandle<R: Resources> {
    raw: <R as Resources>::Buffer,
}
impl<R: Resources> Copy for BufferHandle<R> {}

enum Res {}
impl Resources for Res {
    type Buffer = u32;
}
impl Copy for Res { }

fn main() {
    let b: BufferHandle<Res> = BufferHandle { raw: 1 };
    let c = b;
    assert_eq!(c.raw, b.raw)
}
<|endoftext|>


<commit_before>use alloc::boxed::Box;

use collections::vec::Vec;

use common::memory;

use disk::Disk;

use drivers::pciconfig::PciConfig;

use schemes::Result;

use self::hba::{HbaMem, HbaPort, HbaPortType};

pub mod fis;
pub mod hba;

pub struct Ahci;

impl Ahci {
    pub fn disks(mut pci: PciConfig) -> Vec<Box<Disk>> {
        let mut ret: Vec<Box<Disk>> = Vec::new();

        let base = unsafe { (pci.read(0x24) & 0xFFFFFFF0) as usize };
        let irq = unsafe { (pci.read(0x3C) & 0xF) as u8 };

        debugln!("AHCI on: {:X} IRQ: {:X}", base as usize, irq);

        let pi = unsafe { &mut * (base as *mut HbaMem) }.pi.read();

        for i in 0..32 {
            if pi & 1 << i == 1 << i {
                let mut disk = box AhciDisk::new(base, i);
                let port_type = disk.port.probe();
                debugln!("Port {}: {:?}", i, port_type);
                match port_type {
                    HbaPortType::SATA => {
                        disk.port.init();
                        ret.push(disk);
                    },
                    _ => ()
                }
            }
        }

        ret
    }
}

pub struct AhciDisk {
    port: &'static mut HbaPort
}

impl AhciDisk {
    fn new(base: usize, port_index: usize) -> Self {
        AhciDisk {
            port: &mut unsafe { &mut * (base as *mut HbaMem) }.ports[port_index]
        }
    }
}

impl Disk for AhciDisk {
    fn read(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize> {
        self.port.ata_dma(block, buffer.len()/512, buffer.as_ptr() as usize, false)
    }

    fn write(&mut self, block: u64, buffer: &[u8]) -> Result<usize> {
        self.port.ata_dma(block, buffer.len()/512, buffer.as_ptr() as usize, true)
    }
}
<commit_msg>Refactor `Ahci::disks()` with combinators and no mut<commit_after>use alloc::boxed::Box;

use collections::vec::Vec;

use common::memory;

use disk::Disk;

use drivers::pciconfig::PciConfig;

use schemes::Result;

use self::hba::{HbaMem, HbaPort, HbaPortType};

pub mod fis;
pub mod hba;

pub struct Ahci;

impl Ahci {
    pub fn disks(mut pci: PciConfig) -> Vec<Box<Disk>> {
        let base = unsafe { (pci.read(0x24) & 0xFFFFFFF0) as usize };
        let irq = unsafe { (pci.read(0x3C) & 0xF) as u8 };

        debugln!("AHCI on: {:X} IRQ: {:X}", base as usize, irq);

        let pi = unsafe { &mut * (base as *mut HbaMem) }.pi.read();
        let ret: Vec<Box<Disk>> = (0..32)
            .filter(|&i| pi & 1 << i as i32 == 1 << i as i32)
            .filter_map(|i| {
                let mut disk = box AhciDisk::new(base, i);
                let port_type = disk.port.probe();
                debugln!("Port {}: {:?}", i, port_type);
                match port_type {
                    HbaPortType::SATA => {
                        disk.port.init();
                        Some(disk as Box<Disk>)
                    },
                    _ => None
                }
            })
            .collect();

        ret
    }
}

pub struct AhciDisk {
    port: &'static mut HbaPort
}

impl AhciDisk {
    fn new(base: usize, port_index: usize) -> Self {
        AhciDisk {
            port: &mut unsafe { &mut * (base as *mut HbaMem) }.ports[port_index]
        }
    }
}

impl Disk for AhciDisk {
    fn read(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize> {
        self.port.ata_dma(block, buffer.len()/512, buffer.as_ptr() as usize, false)
    }

    fn write(&mut self, block: u64, buffer: &[u8]) -> Result<usize> {
        self.port.ata_dma(block, buffer.len()/512, buffer.as_ptr() as usize, true)
    }
}
<|endoftext|>


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

// More checks that stability attributes are used correctly

#![feature(staged_api)]
#![staged_api]

#[stable(feature = "a", feature = "b", since = "1.0.0")] //~ ERROR multiple 'feature' items
fn f1() { }

#[stable(feature = "a", sinse = "1.0.0")] //~ ERROR unknown meta item 'sinse'
fn f2() { }

#[unstable(feature = "a", issue = "no")] //~ ERROR incorrect 'issue'
fn f3() { }

fn main() { }
<|endoftext|>


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

#![feature(unboxed_closures)]

// Tests that we can't move out of an unboxed closure environment
// if the upvar is captured by ref or the closure takes self by
// reference.

fn main() {
    // By-ref cases
    {
        let x = box 0u;
        let f = |&:| drop(x); //~ cannot move
    }
    {
        let x = box 0u;
        let f = |&mut:| drop(x); //~ cannot move
    }
    {
        let x = box 0u;
        let f = |:| drop(x); //~ cannot move
    }
    // By-value cases
    {
        let x = box 0u;
        let f = move |&:| drop(x); //~ cannot move
    }
    {
        let x = box 0u;
        let f = move |&mut:| drop(x); //~ cannot move
    }
    {
        let x = box 0u;
        let f = move |:| drop(x); // this one is ok
    }
}
<|endoftext|>


<commit_before><commit_msg>Run cargo xtask codegen<commit_after>type Foo = fn(_: bar);
<|endoftext|>


<commit_before><commit_msg>Fix oopsie<commit_after><|endoftext|>


<commit_before>use super::prelude::v1::*;
use super::hash::*;
use super::mem;
use super::fmt::{Debug, Display};

/// An linked list (used for entries)
#[derive(Clone)]
pub enum LinkedList<T: Clone> {
    Elem(T, Box<LinkedList<T>>),
    Nil,
}

impl<T: Clone> LinkedList<T> {
    /// Follow
    pub fn follow(&self) -> Option<&Self> {
        use self::LinkedList::*;
        match *self {
            Elem(_, box ref l) => {
                Some(l)
            },
            Nil => {
                None
            },
        }
    }

    /// Follow mutable
    pub fn follow_mut(&mut self) -> Option<&mut Self> {
        use self::LinkedList::*;
        match *self {
            Elem(_, box ref mut l) => {
                Some(l)
            },
            Nil => {
                None
            },
        }
    }

    /// Push (consumes the list)
    pub fn push(self, elem: T) -> Self {
        LinkedList::Elem(elem, Box::new(self))
    }
}

/// A entry in the hash map
#[derive(Clone)]
pub struct Entry<K: Clone, V: Clone> {
    data: LinkedList<(K, V)>,
}

impl<K: PartialEq<K> + Clone + Debug + Display, V: Clone> Entry<K, V> {
    /// Create new
    pub fn new(key: K, value: V) -> Self {
        Entry {
            data: LinkedList::Elem((key, value), Box::new(LinkedList::Nil)),
        }
    }

    /// Get value from entry
    pub fn get(&self, key: &K) -> Option<&V> {
        let mut cur = Some(&self.data);

        loop {
            cur = match cur {
                Some(&LinkedList::Elem((ref k, ref v), ref l)) => {
                    debugln!("Check key against: {:?}", k);
                    if key == k {
                        return Some(v);
                    } else {
                        l.follow()
                    }
                },
                _ => {
                    return None;
                },
            }
        }

    }

    /// Get value mutable from entry
    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {

        let mut cur = Some(&mut self.data);

        loop {
            cur = match cur {
                Some(x) => match *x {
                    LinkedList::Elem((ref k, ref mut v), ref mut l) => {
                        debugln!("Check key against: {}", k);
                        if key == k {
                            return Some(v);
                        } else {
                            l.follow_mut()
                        }
                    },
                    LinkedList::Nil => {
                        return None;
                    },
                },
                None => {
                    return None;
                },
            }

        }
    }

    /// Push to the list (consumes the entry returning the new one)
    pub fn push(self, key: K, value: V) -> Self {
        Entry {
            data: self.data.push((key, value)),
        }
    }
}

/// A hashtable
pub struct HashMap<K: Clone, V: Clone> {
    data: [Entry<K, V>; 256],
}

impl<K: Hash + PartialEq + Clone + Debug + Display, V: Clone + Debug> HashMap<K, V> {
    /// Make new HT
    pub fn new() -> Self {
        HashMap {
            // Sorry, but LinkedList is not, and will not be copyable
            data: [Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil} , Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}],
        }
    }

    /// Get entry num
    fn get_entry(key: &K) -> usize {
        let mut s = Djb2::new();
        key.hash(&mut s);
        let res = (s.finish() % 256) as usize;
        debugln!("Res is: {}", res);
        res
    }

    /// Get value
    pub fn get(&self, key: &K) -> Option<&V> {
        self.data[Self::get_entry(key)].get(key)
    }

    /// Get value mutable
    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
        self.data[Self::get_entry(key)].get_mut(key)
    }

    /// Set value (return the previous one if overwritten)
    pub fn insert(&mut self, key: K, val: V) -> Option<V> {
        match self.get_mut(&key) {
            Some(r) => {
                debugln!("Key inserted: {:?}", key);
                debugln!("Old val: {:?}", r);
                debugln!("New val: {:?}", val);
                return Some(mem::replace(r, val));
            },
            _ => {}
        }
        let n = Self::get_entry(&key);
        self.data[n] = self.data[n].clone().push(key, val);
        None
    }
}

/// DJB2 hashing
pub struct Djb2 {
    state: u64,
}

impl Djb2 {
    /// Create new DJB2 hasher
    pub fn new() -> Self {
        Djb2 {
            state: 5381,
        }
    }
}

impl Hasher for Djb2 {
    fn finish(&self) -> u64 {
        self.state
    }
    fn write(&mut self, bytes: &[u8]) {
        for &b in bytes {
            self.state = ((self.state << 5) + self.state) + b as u64;
        }
    }
}

pub fn test() {
    let mut ht = HashMap::new();

    ht.insert(2123, 42);
    assert_eq!(ht.get(&2123), Some(&42));
    assert_eq!(ht.get(&1084), None);

    for i in 1..80000 {
        debugln!("Set {}", i);
        ht.insert(i, i);
    }

    for i in 1..2000 {
        debugln!("Get {}", i);
        assert_eq!(ht.get_mut(&i), Some(&i));
    }

}
<commit_msg>Fix error<commit_after>use super::prelude::v1::*;
use super::hash::*;
use super::mem;
use super::fmt::{Debug, Display};

/// An linked list (used for entries)
#[derive(Clone)]
pub enum LinkedList<T: Clone> {
    Elem(T, Box<LinkedList<T>>),
    Nil,
}

impl<T: Clone> LinkedList<T> {
    /// Follow
    pub fn follow(&self) -> Option<&Self> {
        use self::LinkedList::*;
        match *self {
            Elem(_, box ref l) => {
                Some(l)
            },
            Nil => {
                None
            },
        }
    }

    /// Follow mutable
    pub fn follow_mut(&mut self) -> Option<&mut Self> {
        use self::LinkedList::*;
        match *self {
            Elem(_, box ref mut l) => {
                Some(l)
            },
            Nil => {
                None
            },
        }
    }

    /// Push (consumes the list)
    pub fn push(self, elem: T) -> Self {
        LinkedList::Elem(elem, Box::new(self))
    }
}

/// A entry in the hash map
#[derive(Clone)]
pub struct Entry<K: Clone, V: Clone> {
    data: LinkedList<(K, V)>,
}

impl<K: PartialEq<K> + Clone + Debug + Display, V: Clone> Entry<K, V> {
    /// Create new
    pub fn new(key: K, value: V) -> Self {
        Entry {
            data: LinkedList::Elem((key, value), Box::new(LinkedList::Nil)),
        }
    }

    /// Get value from entry
    pub fn get(&self, key: &K) -> Option<&V> {
        let mut cur = Some(&self.data);

        loop {
            cur = match cur {
                Some(&LinkedList::Elem((ref k, ref v), ref l)) => {
                    debugln!("Check key against: {:?}", k);
                    if key == k {
                        return Some(v);
                    } else {
                        l.follow()
                    }
                },
                _ => {
                    return None;
                },
            }
        }

    }

    /// Get value mutable from entry
    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {

        let mut cur = Some(&mut self.data);

        loop {
            cur = match cur {
                Some(x) => match *x {
                    LinkedList::Elem((ref k, ref mut v), ref mut l) => {
                        debugln!("Check key against: {}", k);
                        if key == k {
                            return Some(v);
                        } else {
                            l.follow_mut()
                        }
                    },
                    LinkedList::Nil => {
                        return None;
                    },
                },
                None => {
                    return None;
                },
            }

        }
    }

    /// Push to the list (consumes the entry returning the new one)
    pub fn push(self, key: K, value: V) -> Self {
        Entry {
            data: self.data.push((key, value)),
        }
    }
}

/// A hashtable
pub struct HashMap<K: Clone, V: Clone> {
    data: [Entry<K, V>; 256],
}

impl<K: Hash + PartialEq + Clone + Debug + Display, V: Clone + Debug> HashMap<K, V> {
    /// Make new HT
    pub fn new() -> Self {
        HashMap {
            // Sorry, but LinkedList is not, and will not be copyable
            data: [Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil} , Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}, Entry {data: LinkedList::Nil}],
        }
    }

    /// Get entry num
    fn get_entry(key: &K) -> usize {
        let mut s = Djb2::new();
        key.hash(&mut s);
        let res = (s.finish() % 256) as usize;
        debugln!("Res is: {}", res);
        res
    }

    /// Get value
    pub fn get(&self, key: &K) -> Option<&V> {
        self.data[Self::get_entry(key)].get(key)
    }

    /// Get value mutable
    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
        self.data[Self::get_entry(key)].get_mut(key)
    }

    /// Set value (return the previous one if overwritten)
    pub fn insert(&mut self, key: K, val: V) -> Option<V> {
        match self.get_mut(&key) {
            Some(r) => {
                debugln!("Key inserted: {:?}", key);
                debugln!("Old val: {:?}", r);
                debugln!("New val: {:?}", val);
                return Some(mem::replace(r, val));
            },
            _ => {}
        }
        let n = Self::get_entry(&key);
        self.data[n] = self.data[n].clone().push(key, val);
        None
    }
}

/// DJB2 hashing
pub struct Djb2 {
    state: u64,
}

impl Djb2 {
    /// Create new DJB2 hasher
    pub fn new() -> Self {
        Djb2 {
            state: 5381,
        }
    }
}

impl Hasher for Djb2 {
    fn finish(&self) -> u64 {
        self.state
    }
    fn write(&mut self, bytes: &[u8]) {
        for &b in bytes {
            self.state = ((self.state << 5) + self.state) + b as u64;
        }
    }
}

pub fn test() {
    let mut ht = HashMap::new();

    ht.insert(2123, 42);
    assert_eq!(ht.get(&2123), Some(&42));
    assert_eq!(ht.get(&1084), None);

    for i in 1..100000 {
        debugln!("Set {}", i);
        ht.insert(i, i);
    }

    for i in 1..20000 {
        debugln!("Get {}", i);
        assert_eq!(ht.get(&i), Some(&i));
    }

}
<|endoftext|>