<commit_before>// TODO MOD DOC
use iup_sys;
use std::ptr;
use std::ffi::{CStr, CString};
use callback::CallbackReturn;
use Result;

// TODO the objects could prehaps be copy as they are loose handles?
// it does not implement Clone yet either, so we should pick something.

/// Makes a Vec of `Element` trait objects.
///
/// This actually uses the `Handle` wrapper instead of `Element` due to the Sized requirement.
///
/// This should be passed to functions that expect a list of elements in the constructor and such.
#[macro_export]
macro_rules! elements {
    () => { vec! [] };
    ($($elem:expr),*) => { vec! [ $($crate::element::Handle::from_element($elem)),* ] };
}

/// This macro should be used for every type binding IUP handles.
///
/// See applicable `$classname`s [here][1].  Use a empty string if not applicable.
/// [1]: http://webserver2.tecgraf.puc-rio.br/iup/en/func/iupgetclassname.html
macro_rules! impl_element {
    ($ty_path:path, $classname:expr) => {

        impl $crate::Element for $ty_path {
            #[inline(always)]
            fn dup(&self) -> Self {
                $ty_path(self.0)
            }
            #[inline(always)]
            fn raw(&self) -> *mut iup_sys::Ihandle {
                self.0
            }
            #[inline(always)]
            unsafe fn from_raw_unchecked(ih: *mut iup_sys::Ihandle) -> Self {
                $ty_path(ih)
            }
            #[inline]
            unsafe fn target_classname() -> &'static str {
                $classname
            }
        }

        use std::fmt;
        impl fmt::Debug for $ty_path {
            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
                fmt.write_fmt(format_args!("{}({:p})", stringify!($ty_path), self.raw()))
            }
        }

        impl $crate::callback::DestroyCb for $ty_path {}
        impl $crate::callback::MapCb for $ty_path {}
        impl $crate::callback::UnmapCb for $ty_path {}
        impl $crate::callback::GetFocusCb for $ty_path {}
        impl $crate::callback::KillFocusCb for $ty_path {}
        impl $crate::callback::EnterWindowCb for $ty_path {}
        impl $crate::callback::LeaveWindowCb for $ty_path {}
        impl $crate::callback::HelpCb for $ty_path {}
    };
}

/// An object that can wrap **any** IUP element/handle.
pub struct Handle(*mut iup_sys::Ihandle);

impl Handle {
    /// Constructs from another elementar object.
    pub fn from_element<E: Element>(elem: E) -> Handle {
        Handle(elem.raw())
    }

    /// Converts this handle object into a element object if they are compatible.
    pub fn to_element<E: Element>(self) -> Option<E> {
        if self.can_downcast::<E>() {
            // Since a Handle must be obtained also by using `from_raw` we can assume the handle
            // has reached the Rust binding thought it and thus using `from_raw_unchecked` here.
            Some(unsafe { E::from_raw_unchecked(self.raw()) })
        } else {
            None
        }
    }

    /// Checks if this Element type can be downcasted to the type E.
    fn can_downcast<E: Element>(&self) -> bool {
        // TODO what about filedlg, colordlg and such that are essentially "dialog"?
        let lhs = unsafe { self.classname().to_bytes() };
        let rhs = unsafe { E::target_classname().as_bytes() };
        if lhs.len() > 0 && rhs.len() > 0 {
            lhs == rhs
        } else {
            // In case self (a Handle) is trying to cast to a target object of Handle, let it go.
            rhs == b"__iuprusthandle"
        }
    }
}

impl_element!(Handle, "__iuprusthandle");

/// Every IUP object is an `Element`.
pub trait Element where Self: Sized {

    /// Gets the raw IUP handle associated with this element.
    fn raw(&self) -> *mut iup_sys::Ihandle;

    /// Constructs another object that binds to the same IUP handle as this one.
    fn dup(&self) -> Self;

    /// Constructs an Element from a raw IUP handle.
    ///
    /// # Safety
    /// The `from_raw_unchecked` method is faster than `from_raw` but must be used with care.
    ///
    /// The Rust binding performs important operations and checks when a raw IUP handle reaches
    /// the bounds of safe Rust binding, that only happens when `from_raw` is used. Be sure the
    /// raw handle has reached safe Rust bounds at least once before using this method.
    ///
    /// It's undefined behaviour if the raw handle is incompatible with `Self` bindings.
    unsafe fn from_raw_unchecked(ih: *mut iup_sys::Ihandle) -> Self;

    /// Constructs an Element from a raw IUP handle.
    ///
    /// It's undefined behaviour if the raw handle is incompatible with `Self` bindings.
    ///
    /// # Panics
    /// Panics if the raw handle is a null pointer.
    fn from_raw(ih: *mut iup_sys::Ihandle) -> Self {
        if ih.is_null() {
            panic!("Failed to create IUP Widget from raw handle.")
        } else {
            unsafe {
                // Note: DESTROY_CB is used here instead of LDESTROY_CB because the DESTROY_CB
                // is called later. LDESTROY_CB is used in callback.rs, see it for more details.
                iup_sys::IupSetCallback(ih, str_to_c_str!("DESTROY_CB"), on_element_destroy);
                Element::from_raw_unchecked(ih)
            }
        }
    }

    /// Sets an interface element attribute.
    ///
    /// See also the [IUP Attributes Guide][1].
    ///
    /// [1]: http://webserver2.tecgraf.puc-rio.br/iup/en/attrib_guide.html
    fn set_attrib<S1, S2>(&mut self, name: S1, value: S2) -> Self
                                        where S1: Into<String>, S2: Into<String> {
        // The way IupSetAttribute works is infeasible to safety. Use IupSetStrAttribute.
        let cname = CString::new(name.into()).unwrap();
        let cvalue = CString::new(value.into()).unwrap();
        unsafe { iup_sys::IupSetStrAttribute(self.raw(), cname.as_ptr(), cvalue.as_ptr()) };
        self.dup()
    }

    /// Gets an interface element attribute.
    ///
    /// See also the [IUP Attributes Guide][1].
    ///
    /// [1]: http://webserver2.tecgraf.puc-rio.br/iup/en/attrib_guide.html
    fn attrib<S>(&self, name: S) -> Option<String>
                                  where S: Into<String> {
        // Notice IupGetAttribute does not really give strings but pointers (that may be anything)
        // most (if not all) the default IUP attributes are string values, so we are safe by
        // defaulting to IupGetAttribute. A method should be defined to deal with raw attributes.
        let cname = CString::new(name.into()).unwrap();
        match unsafe { iup_sys::IupGetAttribute(self.raw(), cname.as_ptr()) } {
            cvalue if cvalue.is_null() => None,
            cvalue => Some(string_from_c_str!(cvalue)),
        }
    }

    /// Clears the value associated with an attribute and use the default value.
    fn clear_attrib<S>(&mut self, name: S) where S: Into<String> {
        let cname = CString::new(name.into()).unwrap();
        unsafe { iup_sys::IupSetAttribute(self.raw(), cname.as_ptr(), ptr::null()) };
    }

    /// Removes an attribute from element and its children if the attrib is inheritable.
    ///
    /// It is useful to reset the state of inheritable attributes in a tree of elements.
    fn reset_attrib<S>(&mut self, name: S) where S: Into<String> {
        let cname = CString::new(name.into()).unwrap();
        unsafe { iup_sys::IupResetAttribute(self.raw(), cname.as_ptr()) };
    }

    /// Destroys an interface element and all its children.
    ///
    /// Only dialogs, timers, popup menus and images should be normally destroyed, but **detached**
    /// controls can also be destroyed.
    ///
    /// Menu bars associated with dialogs are automatically destroyed when the dialog is destroyed.
    ///
    /// Images associated with controls are **NOT** automatically destroyed. The application must
    /// destroy them when they are not used anymore.
    fn destroy(self) {
        unsafe { iup_sys::IupDestroy(self.raw()) };
    }

    /// Creates (maps) the native interface objects corresponding to the given IUP interface elements.
    ///
    /// It will also called recursively to create the native element of all the children in the
    /// element's tree.
    ///
    /// The element must be already attached to a mapped container, except the dialog.
    /// A child can only be mapped if its parent is already mapped.
    ///
    /// This function is automatically called before the dialog is shown in
    ///  `Element::show`, `IupShowXY` (TODO) and `IupPopup` (TODO).
    ///
    /// The function returns success if the element is already mapped and if the native creation
    /// was successful.
    fn map(&mut self) -> Result<()> {
        errchk!(unsafe { iup_sys::IupMap(self.raw()) })
    }

    /// Unmap the element from the native system. It will also unmap all its children.
    ///
    /// It will **not** detach the element from its parent, and it will **not** destroy the element.
    fn unmap(&mut self) {
        unsafe { iup_sys::IupUnmap(self.raw()) }
    }

    /// Shows an interfance element.
    ///
    /// Displays a dialog in the current position, or changes a control VISIBLE attribute. If the
    /// dialog needs to be mapped and the current position is not known then the dialog is centered.
    ///
    /// This function can be executed more than once for the same dialog. This will make the dialog
    /// be placed above all other dialogs in the application, changing its Z-order, and update
    /// its position and/or size on screen.
    fn show(&mut self) -> Result<()> {
        errchk!(unsafe { iup_sys::IupShow(self.raw()) })
    }

    /// Hides an interface element.
    ///
    /// This function has the same effect as attributing value "NO" to the interface element’s
    /// VISIBLE attribute.
    fn hide(&mut self) {
        unsafe { iup_sys::IupHide(self.raw()) };
    }

    /// Gets the [class name][1] of this element.
    /// [1]: http://webserver2.tecgraf.puc-rio.br/iup/en/func/iupgetclassname.html
    unsafe fn classname(&self) -> &CStr {
        CStr::from_ptr(iup_sys::IupGetClassName(self.raw()))
    }

    /// Gets the [class name][1] the derived object should be targeting.
    /// [1]: http://webserver2.tecgraf.puc-rio.br/iup/en/func/iupgetclassname.html
    unsafe fn target_classname() -> &'static str;

    // TODO
    // class
    // native handle
    // expand
    // x,y
    // userwidth, userheight
    // naturalwidth, naturalheight
    // currentwidth, currentheight
    // parent
    // first child
    // brother
}

/// Called whenever a Element gets destroyed.
///
/// Use this to perform frees related to the Rust binding that are per-element.
extern fn on_element_destroy(ih: *mut iup_sys::Ihandle) -> iup_sys::CallbackReturn {
    unsafe { ::callback::drop_callbacks(ih); }
    iup_sys::CallbackReturn::Default
}
<commit_msg>Improved downcasting<commit_after>// TODO MOD DOC
use iup_sys;
use std::ptr;
use std::ffi::{CStr, CString};
use callback::CallbackReturn;
use Result;
use std::result;

/// Makes a Vec of `Element` trait objects.
///
/// This actually uses the `Handle` wrapper instead of `Element` due to the Sized requirement.
///
/// This should be passed to functions that expect a list of elements in the constructor and such.
#[macro_export]
macro_rules! elements {
    () => { vec! [] };
    ($($elem:expr),*) => { vec! [ $($crate::element::Handle::from_element($elem)),* ] };
}

/// This macro should be used for every type binding IUP handles.
///
/// See applicable `$classname`s [here][1]. Some classes aren't on the list and should be
/// picked up manually by looking at the IUP source code or by looking at the result
/// of `Element::classname`.
/// [1]: http://webserver2.tecgraf.puc-rio.br/iup/en/func/iupgetclassname.html
macro_rules! impl_element {
    ($ty_path:path, $classname:expr) => {
        impl_element_nofrom!($ty_path, $classname);

        impl From<$ty_path> for $crate::element::Handle {
            fn from(elem: $ty_path) -> $crate::element::Handle {
                $crate::element::Handle::from_element(elem)
                // TODO should Handle::from_element be removed in favor of this from/into method?
            }
        }
    };
}
/// This is called from impl_element! to do all the work.
///
/// This is a necessary thing because if we implemented `From<$ty_path> for Handle` here it'd cause
/// a compilation error during `From<Handle> for Handle`.
macro_rules! impl_element_nofrom {
    ($ty_path:path, $classname:expr) => {

        impl $crate::Element for $ty_path {
            #[inline(always)]
            fn dup(&self) -> Self {
                $ty_path(self.0)
            }
            #[inline(always)]
            fn raw(&self) -> *mut iup_sys::Ihandle {
                self.0
            }
            #[inline(always)]
            unsafe fn from_raw_unchecked(ih: *mut iup_sys::Ihandle) -> Self {
                $ty_path(ih)
            }
            #[inline]
            unsafe fn target_classname() -> &'static str {
                $classname
            }
        }

        use std; // TODO any way to get around this?
        impl std::fmt::Debug for $ty_path {
            fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
                fmt.write_fmt(format_args!("{}({:p})", stringify!($ty_path), self.raw()))
            }
        }

        impl $crate::callback::DestroyCb for $ty_path {}
        impl $crate::callback::MapCb for $ty_path {}
        impl $crate::callback::UnmapCb for $ty_path {}
        impl $crate::callback::GetFocusCb for $ty_path {}
        impl $crate::callback::KillFocusCb for $ty_path {}
        impl $crate::callback::EnterWindowCb for $ty_path {}
        impl $crate::callback::LeaveWindowCb for $ty_path {}
        impl $crate::callback::HelpCb for $ty_path {}
    };
}

/// An object that can wrap **any** IUP element/handle.
pub struct Handle(*mut iup_sys::Ihandle);

impl Handle {
    /// Constructs from another elementar object.
    pub fn from_element<E: Element>(elem: E) -> Handle {
        Handle(elem.raw())
    }

    /// Converts this handle object into a element object if they are compatible.
    pub fn try_downcast<E: Element>(self) -> result::Result<E, Handle> {
        if self.can_downcast::<E>() {
            // Since a Handle must be obtained also by using `from_raw` we can assume the handle
            // has reached the Rust binding thought it and thus using `from_raw_unchecked` here.
            Ok(unsafe { E::from_raw_unchecked(self.raw()) })
        } else {
            Err(self)
        }
    }

    /// Checks if this Element type can be downcasted to the type E.
    fn can_downcast<E: Element>(&self) -> bool {
        let lhs = unsafe { self.classname().to_bytes() };
        let rhs = unsafe { E::target_classname().as_bytes() };
        lhs == rhs || rhs == b"__iuprusthandle"
        // In case self/lhs (a Handle) is trying to cast to a target object of Handle, let it go.
    }
}

impl_element_nofrom!(Handle, "__iuprusthandle");

// TODO the objects could prehaps be Copy as they are loose handles?
// it does not implement Clone yet either, so we should pick something.
// Remove/deprecate the Element::dup method after this choice has been made.

/// Every IUP object is an `Element`.
pub trait Element where Self: Sized {

    /// Constructs a specialized Element object from a general Handle if they are compatible.
    fn from_handle(handle: Handle) -> result::Result<Self, Handle> {
        handle.try_downcast::<Self>()
    }

    /// Constructs an Element from a raw IUP handle.
    ///
    /// # Safety
    /// The `from_raw_unchecked` method is faster than `from_raw` but must be used with care.
    ///
    /// The Rust binding performs important operations and checks when a raw IUP handle reaches
    /// the bounds of safe Rust binding, that only happens when `from_raw` is used. Be sure the
    /// raw handle has reached safe Rust bounds at least once before using this method.
    ///
    /// It's undefined behaviour if the raw handle is incompatible with `Self` bindings.
    unsafe fn from_raw_unchecked(ih: *mut iup_sys::Ihandle) -> Self;

    /// Constructs an Element from a raw IUP handle.
    ///
    /// It's undefined behaviour if the raw handle is incompatible with `Self` bindings.
    ///
    /// # Panics
    /// Panics if the raw handle is a null pointer.
    fn from_raw(ih: *mut iup_sys::Ihandle) -> Self {
        if ih.is_null() {
            panic!("Failed to create IUP element from raw handle because the handle is null.")
        } else {
            unsafe {
                // Note: DESTROY_CB is used here instead of LDESTROY_CB because the DESTROY_CB
                // is called later. LDESTROY_CB is used in callback.rs, see it for more details.
                iup_sys::IupSetCallback(ih, str_to_c_str!("DESTROY_CB"), on_element_destroy);
                Element::from_raw_unchecked(ih)
            }
        }
    }

    /// Gets the raw IUP handle associated with this element.
    fn raw(&self) -> *mut iup_sys::Ihandle;

    /// Constructs another object that binds to the same IUP handle as this one.
    fn dup(&self) -> Self;

    /// Sets an interface element attribute.
    ///
    /// See also the [IUP Attributes Guide][1].
    ///
    /// [1]: http://webserver2.tecgraf.puc-rio.br/iup/en/attrib_guide.html
    fn set_attrib<S1, S2>(&mut self, name: S1, value: S2) -> Self
                                        where S1: Into<String>, S2: Into<String> {
        // The way IupSetAttribute works is infeasible to safety. Use IupSetStrAttribute.
        let cname = CString::new(name.into()).unwrap();
        let cvalue = CString::new(value.into()).unwrap();
        unsafe { iup_sys::IupSetStrAttribute(self.raw(), cname.as_ptr(), cvalue.as_ptr()) };
        self.dup()
    }

    /// Gets an interface element attribute.
    ///
    /// See also the [IUP Attributes Guide][1].
    ///
    /// [1]: http://webserver2.tecgraf.puc-rio.br/iup/en/attrib_guide.html
    fn attrib<S>(&self, name: S) -> Option<String>
                                  where S: Into<String> {
        // Notice IupGetAttribute does not really give strings but pointers (that may be anything)
        // most (if not all) the default IUP attributes are string values, so we are safe by
        // defaulting to IupGetAttribute. A method should be defined to deal with raw attributes.
        let cname = CString::new(name.into()).unwrap();
        match unsafe { iup_sys::IupGetAttribute(self.raw(), cname.as_ptr()) } {
            cvalue if cvalue.is_null() => None,
            cvalue => Some(string_from_c_str!(cvalue)),
        }
    }

    /// Clears the value associated with an attribute and use the default value.
    fn clear_attrib<S>(&mut self, name: S) where S: Into<String> {
        let cname = CString::new(name.into()).unwrap();
        unsafe { iup_sys::IupSetAttribute(self.raw(), cname.as_ptr(), ptr::null()) };
    }

    /// Removes an attribute from element and its children if the attrib is inheritable.
    ///
    /// It is useful to reset the state of inheritable attributes in a tree of elements.
    fn reset_attrib<S>(&mut self, name: S) where S: Into<String> {
        let cname = CString::new(name.into()).unwrap();
        unsafe { iup_sys::IupResetAttribute(self.raw(), cname.as_ptr()) };
    }

    /// Destroys an interface element and all its children.
    ///
    /// Only dialogs, timers, popup menus and images should be normally destroyed, but **detached**
    /// controls can also be destroyed.
    ///
    /// Menu bars associated with dialogs are automatically destroyed when the dialog is destroyed.
    ///
    /// Images associated with controls are **NOT** automatically destroyed. The application must
    /// destroy them when they are not used anymore.
    fn destroy(self) {
        unsafe { iup_sys::IupDestroy(self.raw()) };
    }

    /// Creates (maps) the native interface objects corresponding to the given IUP interface elements.
    ///
    /// It will also called recursively to create the native element of all the children in the
    /// element's tree.
    ///
    /// The element must be already attached to a mapped container, except the dialog.
    /// A child can only be mapped if its parent is already mapped.
    ///
    /// This function is automatically called before the dialog is shown in
    ///  `Element::show`, `IupShowXY` (TODO) and `IupPopup` (TODO).
    ///
    /// The function returns success if the element is already mapped and if the native creation
    /// was successful.
    fn map(&mut self) -> Result<()> {
        errchk!(unsafe { iup_sys::IupMap(self.raw()) })
    }

    /// Unmap the element from the native system. It will also unmap all its children.
    ///
    /// It will **not** detach the element from its parent, and it will **not** destroy the element.
    fn unmap(&mut self) {
        unsafe { iup_sys::IupUnmap(self.raw()) }
    }

    /// Shows an interfance element.
    ///
    /// Displays a dialog in the current position, or changes a control VISIBLE attribute. If the
    /// dialog needs to be mapped and the current position is not known then the dialog is centered.
    ///
    /// This function can be executed more than once for the same dialog. This will make the dialog
    /// be placed above all other dialogs in the application, changing its Z-order, and update
    /// its position and/or size on screen.
    fn show(&mut self) -> Result<()> {
        errchk!(unsafe { iup_sys::IupShow(self.raw()) })
    }

    /// Hides an interface element.
    ///
    /// This function has the same effect as attributing value "NO" to the interface element’s
    /// VISIBLE attribute.
    fn hide(&mut self) {
        unsafe { iup_sys::IupHide(self.raw()) };
    }

    /// Gets the [class name][1] of this element.
    /// [1]: http://webserver2.tecgraf.puc-rio.br/iup/en/func/iupgetclassname.html
    unsafe fn classname(&self) -> &CStr {
        CStr::from_ptr(iup_sys::IupGetClassName(self.raw()))
    }

    /// Gets the [class name][1] the derived object should be targeting.
    /// [1]: http://webserver2.tecgraf.puc-rio.br/iup/en/func/iupgetclassname.html
    unsafe fn target_classname() -> &'static str;

    // TODO
    // class
    // native handle
    // expand
    // x,y
    // userwidth, userheight
    // naturalwidth, naturalheight
    // currentwidth, currentheight
    // parent
    // first child
    // brother
}

/// Called whenever a Element gets destroyed.
///
/// Use this to perform frees related to the Rust binding that are per-element.
extern fn on_element_destroy(ih: *mut iup_sys::Ihandle) -> iup_sys::CallbackReturn {
    unsafe { ::callback::drop_callbacks(ih); }
    iup_sys::CallbackReturn::Default
}
<|endoftext|>


<commit_before>use syn::parse;

mod ast;
mod parser;
mod matching;
mod compiler;
mod aarch64data;
mod encoding_helpers;

use crate::State;
use crate::common::{Size, Stmt, JumpType, emit_error_at};
use crate::arch::Arch;
use self::aarch64data::Relocation;

struct Context<'a, 'b: 'a> {
    pub state: &'a mut State<'b>
}

#[derive(Clone, Debug)]
pub struct ArchAarch64 {

}

impl Default for ArchAarch64 {
    fn default() -> ArchAarch64 {
        ArchAarch64 { }
    }
}

impl Arch for ArchAarch64 {
    fn name(&self) -> &str {
        "aarch64"
    }

    fn set_features(&mut self, features: &[syn::Ident]) {
        if let Some(feature) = features.first() {
            emit_error_at(feature.span(), "Arch aarch64 has no known features".into());
        }
    }

    fn handle_static_reloc(&self, stmts: &mut Vec<Stmt>, reloc: JumpType, size: Size) {
        let span = reloc.span();

        let relocation = match size {
            Size::DWORD => Relocation::LITERAL32,
            Size::QWORD => Relocation::LITERAL64,
            _ => {
                emit_error_at(span, "Relocation of unsupported size for the current target architecture".into());
                return;
            }
        };
        let data = [relocation.to_id()];

        stmts.push(Stmt::Const(0, size));
        stmts.push(reloc.encode(&data));
    }

    fn compile_instruction(&self, state: &mut State, input: parse::ParseStream) -> parse::Result<()> {
        let mut ctx = Context {
            state
        };

        let (instruction, args) = parser::parse_instruction(&mut ctx, input)?;
        let span = instruction.span;

        println!("{:#?}", args);

        let match_data = match matching::match_instruction(&mut ctx, &instruction, args) {
            Err(None) => return Ok(()),
            Err(Some(e)) => {
                emit_error_at(span, e);
                return Ok(())
            }
            Ok(m) => m
        };

        println!("{:#?}", instruction);
        println!("{:#?}", match_data);

        match compiler::compile_instruction(&mut ctx, match_data) {
            Err(None) => return Ok(()),
            Err(Some(e)) => {
                emit_error_at(span, e);
                return Ok(())
            }
            Ok(()) => ()
        }

        Ok(())
    }
}<commit_msg>remove debugging statements<commit_after>use syn::parse;

mod ast;
mod parser;
mod matching;
mod compiler;
mod aarch64data;
mod encoding_helpers;

use crate::State;
use crate::common::{Size, Stmt, JumpType, emit_error_at};
use crate::arch::Arch;
use self::aarch64data::Relocation;

struct Context<'a, 'b: 'a> {
    pub state: &'a mut State<'b>
}

#[derive(Clone, Debug)]
pub struct ArchAarch64 {

}

impl Default for ArchAarch64 {
    fn default() -> ArchAarch64 {
        ArchAarch64 { }
    }
}

impl Arch for ArchAarch64 {
    fn name(&self) -> &str {
        "aarch64"
    }

    fn set_features(&mut self, features: &[syn::Ident]) {
        if let Some(feature) = features.first() {
            emit_error_at(feature.span(), "Arch aarch64 has no known features".into());
        }
    }

    fn handle_static_reloc(&self, stmts: &mut Vec<Stmt>, reloc: JumpType, size: Size) {
        let span = reloc.span();

        let relocation = match size {
            Size::DWORD => Relocation::LITERAL32,
            Size::QWORD => Relocation::LITERAL64,
            _ => {
                emit_error_at(span, "Relocation of unsupported size for the current target architecture".into());
                return;
            }
        };
        let data = [relocation.to_id()];

        stmts.push(Stmt::Const(0, size));
        stmts.push(reloc.encode(&data));
    }

    fn compile_instruction(&self, state: &mut State, input: parse::ParseStream) -> parse::Result<()> {
        let mut ctx = Context {
            state
        };

        let (instruction, args) = parser::parse_instruction(&mut ctx, input)?;
        let span = instruction.span;

        let match_data = match matching::match_instruction(&mut ctx, &instruction, args) {
            Err(None) => return Ok(()),
            Err(Some(e)) => {
                emit_error_at(span, e);
                return Ok(())
            }
            Ok(m) => m
        };

        match compiler::compile_instruction(&mut ctx, match_data) {
            Err(None) => return Ok(()),
            Err(Some(e)) => {
                emit_error_at(span, e);
                return Ok(())
            }
            Ok(()) => ()
        }

        Ok(())
    }
}<|endoftext|>


<commit_before>//! Hello world server.
//!
//! A simple client that opens a TCP stream, writes "hello world\n", and closes
//! the connection.
//!
//! You can test this out by running:
//!
//!     ncat -l 6142
//!
//! And then in another terminal run:
//!
//!     cargo run --example hello_world

#![warn(rust_2018_idioms)]

use tokio::io::AsyncWriteExt;
use tokio::net::TcpStream;

use std::error::Error;

#[tokio::main]
pub async fn main() -> Result<(), Box<dyn Error>> {
    // Open a TCP stream to the socket address.
    //
    // Note that this is the Tokio TcpStream, which is fully async.
    let mut stream = TcpStream::connect("127.0.0.1:6142").await?;
    println!("created stream");

    let result = stream.write(b"hello world\n").await;
    println!("wrote to stream; success={:?}", result.is_ok());

    Ok(())
}
<commit_msg>examples: use `write_all` instead of `write` in hello world example (#5044)<commit_after>//! Hello world server.
//!
//! A simple client that opens a TCP stream, writes "hello world\n", and closes
//! the connection.
//!
//! You can test this out by running:
//!
//!     ncat -l 6142
//!
//! And then in another terminal run:
//!
//!     cargo run --example hello_world

#![warn(rust_2018_idioms)]

use tokio::io::AsyncWriteExt;
use tokio::net::TcpStream;

use std::error::Error;

#[tokio::main]
pub async fn main() -> Result<(), Box<dyn Error>> {
    // Open a TCP stream to the socket address.
    //
    // Note that this is the Tokio TcpStream, which is fully async.
    let mut stream = TcpStream::connect("127.0.0.1:6142").await?;
    println!("created stream");

    let result = stream.write_all(b"hello world\n").await;
    println!("wrote to stream; success={:?}", result.is_ok());

    Ok(())
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate rouille;

use std::io;

fn main() {
    rouille::start_server("localhost:8000", move |request| {
        let _entry = rouille::LogEntry::start(io::stdout(), request);

        if let Ok(r) = rouille::match_assets(request, "examples") {
            return r;
        }

        let response = router!(request,
            GET (/) => (|| {
                Ok(rouille::Response::redirect("/hello/world"))
            }),

            GET (/hello/world) => (|| {
                println!("hello world");
                Err(rouille::RouteError::WrongInput)
            }),

            GET (/{id}) => (|id: u32| {
                println!("u32 {:?}", id);
                Err(rouille::RouteError::WrongInput)
            }),

            GET (/{id}) => (|id: String| {
                println!("String {:?}", id);
                Err(rouille::RouteError::WrongInput)
            }),

            _ => || Err(rouille::RouteError::NoRouteFound)
        );

        response.unwrap_or_else(|err| rouille::Response::from_error(&err))
    });
}
<commit_msg>Update hello world example<commit_after>#[macro_use]
extern crate rouille;

use std::io;

fn main() {
    rouille::start_server("localhost:8000", move |request| {
        let _entry = rouille::LogEntry::start(io::stdout(), request);

        if let Ok(r) = rouille::match_assets(request, "examples") {
            return r;
        }

        let response = router!(request,
            GET (/) => (|| {
                Ok(rouille::Response::redirect("/hello/world"))
            }),

            GET (/hello/world) => (|| {
                println!("hello world");
                Ok(rouille::Response::text("hello world"))
            }),

            GET (/{id}) => (|id: u32| {
                println!("u32 {:?}", id);
                Err(rouille::RouteError::WrongInput)
            }),

            GET (/{id}) => (|id: String| {
                println!("String {:?}", id);
                Ok(rouille::Response::text(format!("hello, {}", id)))
            }),

            _ => || Err(rouille::RouteError::NoRouteFound)
        );

        response.unwrap_or_else(|err| rouille::Response::from_error(&err))
    });
}
<|endoftext|>


<commit_before>// 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.

//! # The Rust Core Library
//!
//! The Rust Core Library is the dependency-free[^free] foundation of [The
//! Rust Standard Library](../std/index.html). It is the portable glue
//! between the language and its libraries, defining the intrinsic and
//! primitive building blocks of all Rust code. It links to no
//! upstream libraries, no system libraries, and no libc.
//!
//! [^free]: Strictly speaking, there are some symbols which are needed but
//!          they aren't always necessary.
//!
//! The core library is *minimal*: it isn't even aware of heap allocation,
//! nor does it provide concurrency or I/O. These things require
//! platform integration, and this library is platform-agnostic.
//!
//! # How to use the core library
//!
//! Please note that all of these details are currently not considered stable.
//!
// FIXME: Fill me in with more detail when the interface settles
//! This library is built on the assumption of a few existing symbols:
//!
//! * `memcpy`, `memcmp`, `memset` - These are core memory routines which are
//!   often generated by LLVM. Additionally, this library can make explicit
//!   calls to these functions. Their signatures are the same as found in C.
//!   These functions are often provided by the system libc, but can also be
//!   provided by the [rlibc crate](https://crates.io/crates/rlibc).
//!
//! * `rust_begin_panic` - This function takes four arguments, a
//!   `fmt::Arguments`, a `&'static str`, and two `u32`'s. These four arguments
//!   dictate the panic message, the file at which panic was invoked, and the
//!   line and column inside the file. It is up to consumers of this core
//!   library to define this panic function; it is only required to never
//!   return. This requires a `lang` attribute named `panic_impl`.
//!
//! * `rust_eh_personality` - is used by the failure mechanisms of the
//!    compiler. This is often mapped to GCC's personality function, but crates
//!    which do not trigger a panic can be assured that this function is never
//!    called. The `lang` attribute is called `eh_personality`.

// Since libcore defines many fundamental lang items, all tests live in a
// separate crate, libcoretest, to avoid bizarre issues.
//
// Here we explicitly #[cfg]-out this whole crate when testing. If we don't do
// this, both the generated test artifact and the linked libtest (which
// transitively includes libcore) will both define the same set of lang items,
// and this will cause the E0152 "duplicate lang item found" error. See
// discussion in #50466 for details.
//
// This cfg won't affect doc tests.
#![cfg(not(test))]

#![stable(feature = "core", since = "1.6.0")]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/",
       html_playground_url = "https://play.rust-lang.org/",
       issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
       test(no_crate_inject, attr(deny(warnings))),
       test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]

#![no_core]
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]

#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(asm)]
#![feature(associated_type_defaults)]
#![feature(attr_literals)]
#![feature(cfg_target_has_atomic)]
#![feature(concat_idents)]
#![feature(const_fn)]
#![feature(const_int_ops)]
#![feature(const_fn_union)]
#![feature(custom_attribute)]
#![feature(doc_cfg)]
#![feature(doc_spotlight)]
#![feature(extern_types)]
#![feature(fundamental)]
#![feature(intrinsics)]
#![feature(lang_items)]
#![feature(link_llvm_intrinsics)]
#![feature(never_type)]
#![feature(exhaustive_patterns)]
#![feature(macro_at_most_once_rep)]
#![feature(no_core)]
#![feature(on_unimplemented)]
#![feature(optin_builtin_traits)]
#![feature(prelude_import)]
#![feature(repr_simd, platform_intrinsics)]
#![feature(rustc_attrs)]
#![feature(rustc_const_unstable)]
#![feature(simd_ffi)]
#![feature(specialization)]
#![feature(staged_api)]
#![feature(stmt_expr_attributes)]
#![feature(unboxed_closures)]
#![feature(untagged_unions)]
#![feature(unwind_attributes)]
#![feature(doc_alias)]
#![feature(mmx_target_feature)]
#![feature(tbm_target_feature)]
#![feature(sse4a_target_feature)]
#![feature(arm_target_feature)]
#![feature(powerpc_target_feature)]
#![feature(mips_target_feature)]
#![feature(aarch64_target_feature)]
#![feature(const_slice_len)]
#![feature(const_str_as_bytes)]
#![feature(const_str_len)]

#[prelude_import]
#[allow(unused)]
use prelude::v1::*;

#[macro_use]
mod macros;

#[macro_use]
mod internal_macros;

#[path = "num/int_macros.rs"]
#[macro_use]
mod int_macros;

#[path = "num/uint_macros.rs"]
#[macro_use]
mod uint_macros;

#[path = "num/isize.rs"] pub mod isize;
#[path = "num/i8.rs"]    pub mod i8;
#[path = "num/i16.rs"]   pub mod i16;
#[path = "num/i32.rs"]   pub mod i32;
#[path = "num/i64.rs"]   pub mod i64;
#[path = "num/i128.rs"]  pub mod i128;

#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"]    pub mod u8;
#[path = "num/u16.rs"]   pub mod u16;
#[path = "num/u32.rs"]   pub mod u32;
#[path = "num/u64.rs"]   pub mod u64;
#[path = "num/u128.rs"]  pub mod u128;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

#[macro_use]
pub mod num;

/* The libcore prelude, not as all-encompassing as the libstd prelude */

pub mod prelude;

/* Core modules for ownership management */

pub mod intrinsics;
pub mod mem;
pub mod ptr;
pub mod hint;

/* Core language traits */

pub mod marker;
pub mod ops;
pub mod cmp;
pub mod clone;
pub mod default;
pub mod convert;
pub mod borrow;

/* Core types and methods on primitives */

pub mod any;
pub mod array;
pub mod ascii;
pub mod sync;
pub mod cell;
pub mod char;
pub mod panic;
pub mod panicking;
pub mod iter;
pub mod option;
pub mod raw;
pub mod result;

pub mod slice;
pub mod str;
pub mod hash;
pub mod fmt;
pub mod time;

pub mod unicode;

/* Async */
pub mod future;
pub mod task;

/* Heap memory allocator trait */
#[allow(missing_docs)]
pub mod alloc;

// note: does not need to be public
mod iter_private;
mod nonzero;
mod tuple;
mod unit;

// Pull in the the `coresimd` crate directly into libcore. This is where all the
// architecture-specific (and vendor-specific) intrinsics are defined. AKA
// things like SIMD and such. Note that the actual source for all this lies in a
// different repository, rust-lang-nursery/stdsimd. That's why the setup here is
// a bit wonky.
#[allow(unused_macros)]
macro_rules! test_v16 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! test_v32 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! test_v64 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! test_v128 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! test_v256 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! test_v512 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! vector_impl { ($([$f:ident, $($args:tt)*]),*) => { $($f!($($args)*);)* } }
#[path = "../stdsimd/coresimd/mod.rs"]
#[allow(missing_docs, missing_debug_implementations, dead_code, unused_imports)]
#[unstable(feature = "stdsimd", issue = "48556")]
#[cfg(not(stage0))] // allow changes to how stdsimd works in stage0
mod coresimd;

#[stable(feature = "simd_arch", since = "1.27.0")]
#[cfg(not(stage0))]
pub use coresimd::arch;
<commit_msg>[nll] libcore: enable feature(nll) for bootstrap<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.

//! # The Rust Core Library
//!
//! The Rust Core Library is the dependency-free[^free] foundation of [The
//! Rust Standard Library](../std/index.html). It is the portable glue
//! between the language and its libraries, defining the intrinsic and
//! primitive building blocks of all Rust code. It links to no
//! upstream libraries, no system libraries, and no libc.
//!
//! [^free]: Strictly speaking, there are some symbols which are needed but
//!          they aren't always necessary.
//!
//! The core library is *minimal*: it isn't even aware of heap allocation,
//! nor does it provide concurrency or I/O. These things require
//! platform integration, and this library is platform-agnostic.
//!
//! # How to use the core library
//!
//! Please note that all of these details are currently not considered stable.
//!
// FIXME: Fill me in with more detail when the interface settles
//! This library is built on the assumption of a few existing symbols:
//!
//! * `memcpy`, `memcmp`, `memset` - These are core memory routines which are
//!   often generated by LLVM. Additionally, this library can make explicit
//!   calls to these functions. Their signatures are the same as found in C.
//!   These functions are often provided by the system libc, but can also be
//!   provided by the [rlibc crate](https://crates.io/crates/rlibc).
//!
//! * `rust_begin_panic` - This function takes four arguments, a
//!   `fmt::Arguments`, a `&'static str`, and two `u32`'s. These four arguments
//!   dictate the panic message, the file at which panic was invoked, and the
//!   line and column inside the file. It is up to consumers of this core
//!   library to define this panic function; it is only required to never
//!   return. This requires a `lang` attribute named `panic_impl`.
//!
//! * `rust_eh_personality` - is used by the failure mechanisms of the
//!    compiler. This is often mapped to GCC's personality function, but crates
//!    which do not trigger a panic can be assured that this function is never
//!    called. The `lang` attribute is called `eh_personality`.

// Since libcore defines many fundamental lang items, all tests live in a
// separate crate, libcoretest, to avoid bizarre issues.
//
// Here we explicitly #[cfg]-out this whole crate when testing. If we don't do
// this, both the generated test artifact and the linked libtest (which
// transitively includes libcore) will both define the same set of lang items,
// and this will cause the E0152 "duplicate lang item found" error. See
// discussion in #50466 for details.
//
// This cfg won't affect doc tests.
#![cfg(not(test))]

#![stable(feature = "core", since = "1.6.0")]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/",
       html_playground_url = "https://play.rust-lang.org/",
       issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
       test(no_crate_inject, attr(deny(warnings))),
       test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]

#![no_core]
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]

#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(asm)]
#![feature(associated_type_defaults)]
#![feature(attr_literals)]
#![feature(cfg_target_has_atomic)]
#![feature(concat_idents)]
#![feature(const_fn)]
#![feature(const_int_ops)]
#![feature(const_fn_union)]
#![feature(custom_attribute)]
#![feature(doc_cfg)]
#![feature(doc_spotlight)]
#![feature(extern_types)]
#![feature(fundamental)]
#![feature(intrinsics)]
#![feature(lang_items)]
#![feature(link_llvm_intrinsics)]
#![feature(never_type)]
#![cfg_attr(not(stage0), feature(nll))]
#![feature(exhaustive_patterns)]
#![feature(macro_at_most_once_rep)]
#![feature(no_core)]
#![feature(on_unimplemented)]
#![feature(optin_builtin_traits)]
#![feature(prelude_import)]
#![feature(repr_simd, platform_intrinsics)]
#![feature(rustc_attrs)]
#![feature(rustc_const_unstable)]
#![feature(simd_ffi)]
#![feature(specialization)]
#![feature(staged_api)]
#![feature(stmt_expr_attributes)]
#![feature(unboxed_closures)]
#![feature(untagged_unions)]
#![feature(unwind_attributes)]
#![feature(doc_alias)]
#![feature(mmx_target_feature)]
#![feature(tbm_target_feature)]
#![feature(sse4a_target_feature)]
#![feature(arm_target_feature)]
#![feature(powerpc_target_feature)]
#![feature(mips_target_feature)]
#![feature(aarch64_target_feature)]
#![feature(const_slice_len)]
#![feature(const_str_as_bytes)]
#![feature(const_str_len)]

#[prelude_import]
#[allow(unused)]
use prelude::v1::*;

#[macro_use]
mod macros;

#[macro_use]
mod internal_macros;

#[path = "num/int_macros.rs"]
#[macro_use]
mod int_macros;

#[path = "num/uint_macros.rs"]
#[macro_use]
mod uint_macros;

#[path = "num/isize.rs"] pub mod isize;
#[path = "num/i8.rs"]    pub mod i8;
#[path = "num/i16.rs"]   pub mod i16;
#[path = "num/i32.rs"]   pub mod i32;
#[path = "num/i64.rs"]   pub mod i64;
#[path = "num/i128.rs"]  pub mod i128;

#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"]    pub mod u8;
#[path = "num/u16.rs"]   pub mod u16;
#[path = "num/u32.rs"]   pub mod u32;
#[path = "num/u64.rs"]   pub mod u64;
#[path = "num/u128.rs"]  pub mod u128;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

#[macro_use]
pub mod num;

/* The libcore prelude, not as all-encompassing as the libstd prelude */

pub mod prelude;

/* Core modules for ownership management */

pub mod intrinsics;
pub mod mem;
pub mod ptr;
pub mod hint;

/* Core language traits */

pub mod marker;
pub mod ops;
pub mod cmp;
pub mod clone;
pub mod default;
pub mod convert;
pub mod borrow;

/* Core types and methods on primitives */

pub mod any;
pub mod array;
pub mod ascii;
pub mod sync;
pub mod cell;
pub mod char;
pub mod panic;
pub mod panicking;
pub mod iter;
pub mod option;
pub mod raw;
pub mod result;

pub mod slice;
pub mod str;
pub mod hash;
pub mod fmt;
pub mod time;

pub mod unicode;

/* Async */
pub mod future;
pub mod task;

/* Heap memory allocator trait */
#[allow(missing_docs)]
pub mod alloc;

// note: does not need to be public
mod iter_private;
mod nonzero;
mod tuple;
mod unit;

// Pull in the the `coresimd` crate directly into libcore. This is where all the
// architecture-specific (and vendor-specific) intrinsics are defined. AKA
// things like SIMD and such. Note that the actual source for all this lies in a
// different repository, rust-lang-nursery/stdsimd. That's why the setup here is
// a bit wonky.
#[allow(unused_macros)]
macro_rules! test_v16 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! test_v32 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! test_v64 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! test_v128 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! test_v256 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! test_v512 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! vector_impl { ($([$f:ident, $($args:tt)*]),*) => { $($f!($($args)*);)* } }
#[path = "../stdsimd/coresimd/mod.rs"]
#[allow(missing_docs, missing_debug_implementations, dead_code, unused_imports)]
#[unstable(feature = "stdsimd", issue = "48556")]
#[cfg(not(stage0))] // allow changes to how stdsimd works in stage0
mod coresimd;

#[stable(feature = "simd_arch", since = "1.27.0")]
#[cfg(not(stage0))]
pub use coresimd::arch;
<|endoftext|>


<commit_before>// 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.

//! # The Rust Core Library
//!
//! The Rust Core Library is the dependency-free foundation of [The
//! Rust Standard Library](../std/index.html). It is the portable glue
//! between the language and its libraries, defining the intrinsic and
//! primitive building blocks of all Rust code. It links to no
//! upstream libraries, no system libraries, and no libc.
//!
//! The core library is *minimal*: it isn't even aware of heap allocation,
//! nor does it provide concurrency or I/O. These things require
//! platform integration, and this library is platform-agnostic.
//!
//! *It is not recommended to use the core library*. The stable
//! functionality of libcore is reexported from the
//! [standard library](../std/index.html). The composition of this library is
//! subject to change over time; only the interface exposed through libstd is
//! intended to be stable.
//!
//! # How to use the core library
//!
// FIXME: Fill me in with more detail when the interface settles
//! This library is built on the assumption of a few existing symbols:
//!
//! * `memcpy`, `memcmp`, `memset` - These are core memory routines which are
//!   often generated by LLVM. Additionally, this library can make explicit
//!   calls to these functions. Their signatures are the same as found in C.
//!   These functions are often provided by the system libc, but can also be
//!   provided by `librlibc` which is distributed with the standard rust
//!   distribution.
//!
//! * `rust_begin_unwind` - This function takes three arguments, a
//!   `fmt::Arguments`, a `&str`, and a `usize`. These three arguments dictate
//!   the panic message, the file at which panic was invoked, and the line.
//!   It is up to consumers of this core library to define this panic
//!   function; it is only required to never return.

// Since libcore defines many fundamental lang items, all tests live in a
// separate crate, libcoretest, to avoid bizarre issues.

// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "core"]
#![unstable(feature = "core")]
#![staged_api]
#![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/",
       html_playground_url = "http://play.rust-lang.org/")]

#![feature(no_std)]
#![no_std]
#![allow(raw_pointer_derive)]
#![deny(missing_docs)]

#![feature(int_uint)]
#![feature(intrinsics, lang_items)]
#![feature(on_unimplemented)]
#![feature(simd, unsafe_destructor)]
#![feature(staged_api)]
#![feature(unboxed_closures)]
#![feature(rustc_attrs)]
#![feature(optin_builtin_traits)]
#![feature(concat_idents)]

#[macro_use]
mod macros;

#[macro_use]
mod cmp_macros;

#[path = "num/float_macros.rs"]
#[macro_use]
mod float_macros;

#[path = "num/int_macros.rs"]
#[macro_use]
mod int_macros;

#[path = "num/uint_macros.rs"]
#[macro_use]
mod uint_macros;

#[path = "num/isize.rs"]  pub mod isize;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

pub mod num;

/* The libcore prelude, not as all-encompassing as the libstd prelude */

pub mod prelude;

/* Core modules for ownership management */

pub mod intrinsics;
pub mod mem;
pub mod nonzero;
pub mod ptr;

/* Core language traits */

pub mod marker;
pub mod ops;
pub mod cmp;
pub mod clone;
pub mod default;

/* Core types and methods on primitives */

pub mod any;
pub mod atomic;
pub mod cell;
pub mod char;
pub mod panicking;
pub mod finally;
pub mod iter;
pub mod option;
pub mod raw;
pub mod result;
pub mod simd;
pub mod slice;
pub mod str;
pub mod hash;
pub mod fmt;
pub mod error;

#[doc(primitive = "bool")]
mod bool {
}

// note: does not need to be public
mod tuple;
mod array;

#[doc(hidden)]
mod core {
    pub use panicking;
    pub use fmt;
    pub use clone;
    pub use cmp;
    pub use hash;
    pub use marker;
    pub use option;
    pub use iter;
}

#[doc(hidden)]
mod std {
    // range syntax
    pub use ops;
}
<commit_msg>Rollup merge of #23100 - wesleywiser:fix_23059, r=brson<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.

//! # The Rust Core Library
//!
//! The Rust Core Library is the dependency-free foundation of [The
//! Rust Standard Library](../std/index.html). It is the portable glue
//! between the language and its libraries, defining the intrinsic and
//! primitive building blocks of all Rust code. It links to no
//! upstream libraries, no system libraries, and no libc.
//!
//! The core library is *minimal*: it isn't even aware of heap allocation,
//! nor does it provide concurrency or I/O. These things require
//! platform integration, and this library is platform-agnostic.
//!
//! *It is not recommended to use the core library*. The stable
//! functionality of libcore is reexported from the
//! [standard library](../std/index.html). The composition of this library is
//! subject to change over time; only the interface exposed through libstd is
//! intended to be stable.
//!
//! # How to use the core library
//!
// FIXME: Fill me in with more detail when the interface settles
//! This library is built on the assumption of a few existing symbols:
//!
//! * `memcpy`, `memcmp`, `memset` - These are core memory routines which are
//!   often generated by LLVM. Additionally, this library can make explicit
//!   calls to these functions. Their signatures are the same as found in C.
//!   These functions are often provided by the system libc, but can also be
//!   provided by the [rlibc crate](https://crates.io/crates/rlibc).
//!
//! * `rust_begin_unwind` - This function takes three arguments, a
//!   `fmt::Arguments`, a `&str`, and a `usize`. These three arguments dictate
//!   the panic message, the file at which panic was invoked, and the line.
//!   It is up to consumers of this core library to define this panic
//!   function; it is only required to never return.

// Since libcore defines many fundamental lang items, all tests live in a
// separate crate, libcoretest, to avoid bizarre issues.

// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "core"]
#![unstable(feature = "core")]
#![staged_api]
#![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/",
       html_playground_url = "http://play.rust-lang.org/")]

#![feature(no_std)]
#![no_std]
#![allow(raw_pointer_derive)]
#![deny(missing_docs)]

#![feature(int_uint)]
#![feature(intrinsics, lang_items)]
#![feature(on_unimplemented)]
#![feature(simd, unsafe_destructor)]
#![feature(staged_api)]
#![feature(unboxed_closures)]
#![feature(rustc_attrs)]
#![feature(optin_builtin_traits)]
#![feature(concat_idents)]

#[macro_use]
mod macros;

#[macro_use]
mod cmp_macros;

#[path = "num/float_macros.rs"]
#[macro_use]
mod float_macros;

#[path = "num/int_macros.rs"]
#[macro_use]
mod int_macros;

#[path = "num/uint_macros.rs"]
#[macro_use]
mod uint_macros;

#[path = "num/isize.rs"]  pub mod isize;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

pub mod num;

/* The libcore prelude, not as all-encompassing as the libstd prelude */

pub mod prelude;

/* Core modules for ownership management */

pub mod intrinsics;
pub mod mem;
pub mod nonzero;
pub mod ptr;

/* Core language traits */

pub mod marker;
pub mod ops;
pub mod cmp;
pub mod clone;
pub mod default;

/* Core types and methods on primitives */

pub mod any;
pub mod atomic;
pub mod cell;
pub mod char;
pub mod panicking;
pub mod finally;
pub mod iter;
pub mod option;
pub mod raw;
pub mod result;
pub mod simd;
pub mod slice;
pub mod str;
pub mod hash;
pub mod fmt;
pub mod error;

#[doc(primitive = "bool")]
mod bool {
}

// note: does not need to be public
mod tuple;
mod array;

#[doc(hidden)]
mod core {
    pub use panicking;
    pub use fmt;
    pub use clone;
    pub use cmp;
    pub use hash;
    pub use marker;
    pub use option;
    pub use iter;
}

#[doc(hidden)]
mod std {
    // range syntax
    pub use ops;
}
<|endoftext|>


<commit_before>#![deny(warnings)]

extern crate postgres;

use std::collections::HashSet;

use postgres::Transaction;
use postgres::Result as PgResult;

struct A<'a, 'b: 'a> {
    t: &'a Transaction<'b>,
}

pub type Step = Box<FnMut(A) -> PgResult<()> + 'static>;

pub struct Migration {
    version: i64,
    up: Step,
    down: Step,
}

pub struct Manager<'a> {
    tx: Transaction<'a>,
    versions: HashSet<i64>,
}

impl Migration {
    fn mk(version: i64, up: Step, down: Step) -> Migration {
        Migration { version: version, up: up, down: down }
    }

    pub fn new<F1, F2>(version: i64, mut up: F1, mut down: F2) -> Migration
                       where F1: FnMut(&Transaction) -> PgResult<()> + 'static,
                             F2: FnMut(&Transaction) -> PgResult<()> + 'static
    {
        Migration::mk(version,
                      Box::new(move |a| up(a.t)),
                      Box::new(move |a| down(a.t)))
    }

    pub fn run(version: i64, up: &str, down: &str) -> Migration {
        Migration::mk(version,
                      run(up.to_string()),
                      run(down.to_string()))
    }

    pub fn add_table(version: i64, table: &str, rest: &str) -> Migration {
        let add_sql = format!("CREATE TABLE {} ({})", table, rest);
        let rm_sql = format!("DROP TABLE {}", table);
        Migration::mk(version, run(add_sql), run(rm_sql))
    }

    pub fn add_column(version: i64, table: &str, column: &str,
                      type_and_constraints: &str) -> Migration {
        let add_sql = format!("ALTER TABLE {} ADD COLUMN {} {}",
                              table, column, type_and_constraints);
        let rm_sql = format!("ALTER TABLE {} DROP COLUMN {}", table, column);
        Migration::mk(version, run(add_sql), run(rm_sql))
    }

    pub fn version(&self) -> i64 { self.version }
}

fn run(sql: String) -> Step {
    Box::new(move |a: A| {
        let tx = a.t;
        tx.execute(&sql, &[]).map(|_| ()).map_err(|e| {
            println!("failed to run `{}`", sql);
            e
        })
    })
}

impl<'a> Manager<'a> {
    pub fn new(tx: postgres::Transaction) -> PgResult<Manager> {
        let mut mgr = Manager { tx: tx, versions: HashSet::new() };
        try!(mgr.load());
        Ok(mgr)
    }

    fn load(&mut self) -> PgResult<()> {
        try!(self.tx.execute("CREATE TABLE IF NOT EXISTS schema_migrations (
            id              SERIAL PRIMARY KEY,
            version         INT8 NOT NULL UNIQUE
        )", &[]));

        let stmt = try!(self.tx.prepare("SELECT version FROM \
                                         schema_migrations"));
        for row in try!(stmt.query(&[])) {
            assert!(self.versions.insert(row.get("version")));
        }
        Ok(())
    }

    pub fn contains(&self, version: i64) -> bool {
        self.versions.contains(&version)
    }

    pub fn apply(&mut self, mut migration: Migration) -> PgResult<()> {
        if !self.versions.insert(migration.version) { return Ok(()) }
        println!("applying {}", migration.version);
        try!((migration.up)(A { t: &self.tx }));
        let stmt = try!(self.tx.prepare("INSERT into schema_migrations
                                         (version) VALUES ($1)"));
        try!(stmt.execute(&[&migration.version]));
        Ok(())
    }

    pub fn rollback(&mut self, mut migration: Migration) -> PgResult<()> {
        if !self.versions.remove(&migration.version) { return Ok(()) }
        println!("rollback {}", migration.version);
        try!((migration.down)(A { t: &self.tx }));
        let stmt = try!(self.tx.prepare("DELETE FROM schema_migrations
                                         WHERE version = $1"));
        try!(stmt.execute(&[&migration.version]));
        Ok(())
    }

    pub fn set_commit(&mut self) { self.tx.set_commit() }

    pub fn finish(self) -> PgResult<()> { self.tx.finish() }
}

#[cfg(test)]
mod tests {
    use std::os;
    use postgres::{PostgresConnection, NoSsl};
    use super::{Manager, Migration};

    fn conn() -> PostgresConnection {
        let url = os::getenv("MIGRATE_TEST_DATABASE_URL").unwrap();
        PostgresConnection::connect(&url, &NoSsl).unwrap()
    }

    #[test]
    fn no_reapply() {
        let c = conn();
        let c = c.transaction().unwrap();
        let mut called = false;
        {
            let mut mgr = Manager::new(c.transaction().unwrap()).unwrap();
            mgr.apply(Migration::new(1, |_| {
                called = true; Ok(())
            }, |_| panic!())).unwrap();
            mgr.set_commit();
        }
        assert!(called);
        called = false;
        {
            let mut mgr = Manager::new(c.transaction().unwrap()).unwrap();
            mgr.apply(Migration::new(1, |_| {
                called = true; Ok(())
            }, |_| panic!())).unwrap();
            mgr.set_commit();
        }
        assert!(!called);
    }

    #[test]
    fn rollback_then_apply() {
        let c = conn();
        let c = c.transaction().unwrap();
        let mut called = false;
        {
            let mut mgr = Manager::new(c.transaction().unwrap()).unwrap();
            mgr.rollback(Migration::new(1, |_| panic!(), |_| {
                called = true; Ok(())
            })).unwrap();
            mgr.set_commit();
        }
        assert!(!called);
        {
            let mut mgr = Manager::new(c.transaction().unwrap()).unwrap();
            mgr.apply(Migration::new(1, |_| {
                called = true; Ok(())
            }, |_| panic!())).unwrap();
            mgr.set_commit();
        }
        assert!(called);
        called = false;
        {
            let mut mgr = Manager::new(c.transaction().unwrap()).unwrap();
            mgr.rollback(Migration::new(1, |_| panic!(), |_| {
                called = true; Ok(())
            })).unwrap();
            mgr.set_commit();
        }
        assert!(called);
    }
}
<commit_msg>Make the Step type alias private<commit_after>#![deny(warnings)]

extern crate postgres;

use std::collections::HashSet;

use postgres::Transaction;
use postgres::Result as PgResult;

struct A<'a, 'b: 'a> {
    t: &'a Transaction<'b>,
}

type Step = Box<FnMut(A) -> PgResult<()> + 'static>;

pub struct Migration {
    version: i64,
    up: Step,
    down: Step,
}

pub struct Manager<'a> {
    tx: Transaction<'a>,
    versions: HashSet<i64>,
}

impl Migration {
    fn mk(version: i64, up: Step, down: Step) -> Migration {
        Migration { version: version, up: up, down: down }
    }

    pub fn new<F1, F2>(version: i64, mut up: F1, mut down: F2) -> Migration
                       where F1: FnMut(&Transaction) -> PgResult<()> + 'static,
                             F2: FnMut(&Transaction) -> PgResult<()> + 'static
    {
        Migration::mk(version,
                      Box::new(move |a| up(a.t)),
                      Box::new(move |a| down(a.t)))
    }

    pub fn run(version: i64, up: &str, down: &str) -> Migration {
        Migration::mk(version,
                      run(up.to_string()),
                      run(down.to_string()))
    }

    pub fn add_table(version: i64, table: &str, rest: &str) -> Migration {
        let add_sql = format!("CREATE TABLE {} ({})", table, rest);
        let rm_sql = format!("DROP TABLE {}", table);
        Migration::mk(version, run(add_sql), run(rm_sql))
    }

    pub fn add_column(version: i64, table: &str, column: &str,
                      type_and_constraints: &str) -> Migration {
        let add_sql = format!("ALTER TABLE {} ADD COLUMN {} {}",
                              table, column, type_and_constraints);
        let rm_sql = format!("ALTER TABLE {} DROP COLUMN {}", table, column);
        Migration::mk(version, run(add_sql), run(rm_sql))
    }

    pub fn version(&self) -> i64 { self.version }
}

fn run(sql: String) -> Step {
    Box::new(move |a: A| {
        let tx = a.t;
        tx.execute(&sql, &[]).map(|_| ()).map_err(|e| {
            println!("failed to run `{}`", sql);
            e
        })
    })
}

impl<'a> Manager<'a> {
    pub fn new(tx: postgres::Transaction) -> PgResult<Manager> {
        let mut mgr = Manager { tx: tx, versions: HashSet::new() };
        try!(mgr.load());
        Ok(mgr)
    }

    fn load(&mut self) -> PgResult<()> {
        try!(self.tx.execute("CREATE TABLE IF NOT EXISTS schema_migrations (
            id              SERIAL PRIMARY KEY,
            version         INT8 NOT NULL UNIQUE
        )", &[]));

        let stmt = try!(self.tx.prepare("SELECT version FROM \
                                         schema_migrations"));
        for row in try!(stmt.query(&[])) {
            assert!(self.versions.insert(row.get("version")));
        }
        Ok(())
    }

    pub fn contains(&self, version: i64) -> bool {
        self.versions.contains(&version)
    }

    pub fn apply(&mut self, mut migration: Migration) -> PgResult<()> {
        if !self.versions.insert(migration.version) { return Ok(()) }
        println!("applying {}", migration.version);
        try!((migration.up)(A { t: &self.tx }));
        let stmt = try!(self.tx.prepare("INSERT into schema_migrations
                                         (version) VALUES ($1)"));
        try!(stmt.execute(&[&migration.version]));
        Ok(())
    }

    pub fn rollback(&mut self, mut migration: Migration) -> PgResult<()> {
        if !self.versions.remove(&migration.version) { return Ok(()) }
        println!("rollback {}", migration.version);
        try!((migration.down)(A { t: &self.tx }));
        let stmt = try!(self.tx.prepare("DELETE FROM schema_migrations
                                         WHERE version = $1"));
        try!(stmt.execute(&[&migration.version]));
        Ok(())
    }

    pub fn set_commit(&mut self) { self.tx.set_commit() }

    pub fn finish(self) -> PgResult<()> { self.tx.finish() }
}

#[cfg(test)]
mod tests {
    use std::os;
    use postgres::{PostgresConnection, NoSsl};
    use super::{Manager, Migration};

    fn conn() -> PostgresConnection {
        let url = os::getenv("MIGRATE_TEST_DATABASE_URL").unwrap();
        PostgresConnection::connect(&url, &NoSsl).unwrap()
    }

    #[test]
    fn no_reapply() {
        let c = conn();
        let c = c.transaction().unwrap();
        let mut called = false;
        {
            let mut mgr = Manager::new(c.transaction().unwrap()).unwrap();
            mgr.apply(Migration::new(1, |_| {
                called = true; Ok(())
            }, |_| panic!())).unwrap();
            mgr.set_commit();
        }
        assert!(called);
        called = false;
        {
            let mut mgr = Manager::new(c.transaction().unwrap()).unwrap();
            mgr.apply(Migration::new(1, |_| {
                called = true; Ok(())
            }, |_| panic!())).unwrap();
            mgr.set_commit();
        }
        assert!(!called);
    }

    #[test]
    fn rollback_then_apply() {
        let c = conn();
        let c = c.transaction().unwrap();
        let mut called = false;
        {
            let mut mgr = Manager::new(c.transaction().unwrap()).unwrap();
            mgr.rollback(Migration::new(1, |_| panic!(), |_| {
                called = true; Ok(())
            })).unwrap();
            mgr.set_commit();
        }
        assert!(!called);
        {
            let mut mgr = Manager::new(c.transaction().unwrap()).unwrap();
            mgr.apply(Migration::new(1, |_| {
                called = true; Ok(())
            }, |_| panic!())).unwrap();
            mgr.set_commit();
        }
        assert!(called);
        called = false;
        {
            let mut mgr = Manager::new(c.transaction().unwrap()).unwrap();
            mgr.rollback(Migration::new(1, |_| panic!(), |_| {
                called = true; Ok(())
            })).unwrap();
            mgr.set_commit();
        }
        assert!(called);
    }
}
<|endoftext|>


<commit_before>pub use svm::slist::List::{Cons,Nil};
use std::fmt;
use std::ops::Index;

/// Convenience macro for making lists.
///
/// # Example:
///
/// ```
/// # #[macro_use] extern crate seax_svm;
/// # use seax_svm::svm::slist;
/// # use seax_svm::svm::slist::List::{Cons, Nil};
/// # fn main () {
/// assert_eq!(
///     list!(1i32, 2i32, 3i32),
///     Cons(1i32, Box::new(Cons(2i32, Box::new(Cons(3i32, Box::new(Nil))))))
///     );
/// # }
/// ```
#[macro_export]
macro_rules! list(
    ( $e:expr, $($rest:expr),+ ) => ( Cons($e, Box::new(list!( $( $rest ),+ )) ));
    ( $e:expr ) => ( Cons($e, Box::new(Nil)) );
    () => ( @Empty )
);

/// Common functions for an immutable Stack abstract data type.
pub trait Stack<T> {

    /// Push an item to the top of the stack, returning a new stack
    fn push(self, item : T) -> Self;

    /// Pop the top element of the stack. Returns an Option on a T and
    /// a new Stack<T> to replace this.
    fn pop(self)            -> Option<(T, Self)>;

    /// Peek at the top item of the stack.
    ///
    /// Returns Some<T> if there is an item on top of the stack,
    /// and None if the stack is empty.
    fn peek(&self)          -> Option<&T>;

    /// Returns an empty stack.
    fn empty()              -> Self;
}

/// Stack implementation using a cons list
impl<T> Stack<T> for List<T> {

    /// Push an item to the top of the stack, returning a new stack.
    ///
    /// # Examples:
    /// ```
    /// use seax_svm::svm::slist::{List,Stack};
    ///
    /// let mut s: List<isize> = Stack::empty();
    /// assert_eq!(s.peek(), None);
    /// s = s.push(1);
    /// assert_eq!(s.peek(), Some(&1));
    /// s = s.push(6);
    /// assert_eq!(s.peek(), Some(&6));
    /// ```
    fn push(self, item: T) -> List<T> {
        Cons(item, box self)
    }

    /// Pop the top element of the stack.
    ///
    /// Pop the top element of the stack. Returns an
    /// `Option<(T,List<T>)>` containing the top element and a new
    /// `List<T>` with that item removed, or `None` if the stack is
    /// empty.
    ///
    /// # Examples:
    /// ```
    /// # use seax_svm::svm::slist::{List,Stack};
    ///
    /// let mut s: List<isize> = Stack::empty();
    /// s = s.push(2);
    /// s = s.push(1);
    /// let pop_result = s.pop().unwrap();
    /// s = pop_result.1;
    /// assert_eq!(s.peek(), Some(&2));
    /// assert_eq!(pop_result.0, 1);
    /// ```
    fn pop(self) -> Option<(T,List<T>)> {
        match self {
            Cons(item, new_self)    => Some((item, *new_self)),
            Nil                     => None
        }
    }

    fn empty() -> List<T> {
        Nil
    }

    /// Peek at the top element of the stack.
    ///
    /// Peek at the top element of the stack. Returns an `Option<&T>`
    /// with a borrowed pointer to the top element, or `None` if the
    /// stack is empty.
    ///
    /// # Examples:
    /// ```
    /// # use seax_svm::svm::slist::{List,Stack};
    ///
    /// let mut s: List<isize> = Stack::empty();
    /// s = s.push(2);
    /// s = s.push(1);
    /// let pop_result = s.pop().unwrap();
    /// s = pop_result.1;
    /// assert_eq!(s.peek(), Some(&2));
    /// assert_eq!(pop_result.0, 1);
    /// ```
    fn peek(&self) -> Option<&T> {
        match self {
            &Nil => None,
            &Cons(ref it,_) => Some(it)
        }
    }

}

/// Singly-linked cons list.
///
/// This is used internally to represent list primitives in the
/// machine.
#[derive(PartialEq,Clone,Debug)]
pub enum List<T> {
    /// Cons cell containing a `T` and a link to the tail
    Cons(T, Box<List<T>>),
    /// The empty list.
    Nil,
}

/// Public implementation for List.
impl<T> List<T> {

    /// Creates a new empty list
    pub fn new() -> List<T> {
        Nil
    }

    /// Prepends the given item to the list.
    ///
    /// Returns the list containing the new  head item.
    /// This is an O(1) operation.
    pub fn prepend(self, it: T) -> List<T> {
        Cons(it, box self)
    }

    /// Appends an item to the end of the list.
    ///
    /// This is an O(n) operation.
    pub fn append(self, it: T) {
        unimplemented!()
    }

    /// Returns the length of the list.
    pub fn length (&self) -> usize {
        match *self {
            Cons(_, ref tail) => 1 + tail.length(),
            Nil => 0
        }
    }

    /// Provide a forward iterator
    #[inline]
    pub fn iter<'a>(&'a self) -> ListIterator<'a, T> {
        ListIterator{current: self}
    }
}

impl<'a, T> fmt::Display for List<T> where T: fmt::Display{

    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // TODO: replace toString with this
        match *self {
            Cons(ref head, ref tail) => write!(f, "({}, {})", head, tail),
            Nil => write!(f,"nil")
        }
    }
}

/// Wraps a List<T> to allow it to be used as an Iterator<T>
pub struct ListIterator<'a, T:'a> {
    current: &'a List<T>
}

/// Implementation of Iterator for List. This allows iteration by
/// link hopping.
impl<'a, T> Iterator for ListIterator<'a, T> {
    type Item = &'a T;

    /// Get the next element from the list.
    ///
    /// Get the next element from the list. Returns a `Some<T>`, or `Nil`
    /// if at the end of the list.
    ///
    /// # Examples:
    /// ```
    /// # #[macro_use] extern crate seax_svm;
    /// # use seax_svm::svm::slist;
    /// # use seax_svm::svm::slist::List;
    /// # use seax_svm::svm::slist::List::{Cons, Nil};
    /// # fn main () {
    /// let list = list!(1,2,3);
    /// let mut iter = list.iter();
    /// assert_eq!(iter.next().unwrap(), &1);
    /// assert_eq!(iter.next().unwrap(), &2);
    /// assert_eq!(iter.next().unwrap(), &3);
    /// # }
    /// ```
    /// ```
    /// # #[macro_use] extern crate seax_svm;
    /// # use seax_svm::svm::slist;
    /// # use seax_svm::svm::slist::List;
    /// # use seax_svm::svm::slist::List::{Cons, Nil};
    /// # fn main () {
    /// let l: List<isize> = list!(1,2,3,4,5,6);
    /// let mut string = String::new();
    /// for item in l.iter() {
    ///     string.push_str((item.to_string() + ", ").as_slice());
    /// }
    /// assert_eq!(string.as_slice(), "1, 2, 3, 4, 5, 6, ")
    /// # }
    /// ```
    fn next(&mut self) -> Option<&'a T> {
        match self.current {
            &Cons(ref head, box ref tail) => { self.current = tail; Some(head) },
            &Nil => None
        }
    }
}

impl<'a, T> ExactSizeIterator for ListIterator<'a, T> {
    fn len(&self) -> usize {
        self.current.length()
    }
}
/// Implementation of indexing for `List<T>`.
///
/// # Examples:
/// ```
/// # #[macro_use] extern crate seax_svm;
/// # use seax_svm::svm::slist;
/// # use seax_svm::svm::slist::List;
/// # use seax_svm::svm::slist::List::{Cons, Nil};
/// # fn main () {
/// let list = list!(1,2,3,4,5,6);
/// assert_eq!(list[1us], 1);
/// # }
/// ```
impl<T> Index<usize> for List<T> {
    type Output = T;

    fn index<'a>(&'a self, _index: &usize) -> &'a T {
        let mut it = self.iter();
        for _ in 0..*_index-1 {
            it.next();
        }
        it.next().unwrap()
    }
}
/// Implementation of indexing for `List<T>`.
///
/// # Examples:
/// ```
/// # #[macro_use] extern crate seax_svm;
/// # use seax_svm::svm::slist;
/// # use seax_svm::svm::slist::List;
/// # use seax_svm::svm::slist::List::{Cons, Nil};
/// # fn main () {
/// let list = list!(1,2,3,4,5,6);
/// assert_eq!(list[1is], 1);
/// # }
/// ```
impl<T> Index<isize> for List<T> {
    type Output = T;

    fn index<'a>(&'a self, _index: &isize) -> &'a T {
        let mut it = self.iter();
        for _ in 0..*_index-1 {
            it.next();
        }
        it.next().unwrap()
    }
}

#[cfg(test)]
mod tests {
    use super::{List, Stack};
    use super::List::{Cons,Nil};

    #[test]
    fn test_list_length() {
        let full_list: List<i32> = list!(1i32, 2i32, 3i32);
        let empty_list: List<i32> = List::new();
        assert_eq!(full_list.length(), 3);
        assert_eq!(empty_list.length(), 0);
    }

    #[test]
    fn test_list_to_string() {
        let l: List<i32> = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
        assert_eq!(l.to_string(), "(1, (2, (3, nil)))");
    }

    #[test]
    fn test_stack_length() {
        let full_stack: List<i32> = list!(1i32, 2i32, 3i32);
        let empty_stack: List<i32> = Stack::empty();
        assert_eq!(full_stack.length(), 3);
        assert_eq!(empty_stack.length(), 0);
    }

    #[test]
    fn test_stack_peek() {
        let full_stack: List<i32> = list!(1i32, 2i32, 3i32);
        let empty_stack: List<i32> = Stack::empty();
        assert_eq!(full_stack.peek(), Some(&1));
        assert_eq!(empty_stack.peek(), None);
    }

    #[test]
    fn test_stack_push() {
        let mut s: List<i32> = Stack::empty();
        assert_eq!(s.peek(), None);
        s = s.push(1);
        assert_eq!(s.peek(), Some(&1));
        s = s.push(6);
        assert_eq!(s.peek(), Some(&6));
    }

    #[test]
    fn test_stack_pop() {
        let mut s: List<i32> = Stack::empty();
        assert_eq!(s.peek(), None);
        s = s.push(1);
        assert_eq!(s.peek(), Some(&1));
        s = s.push(6);
        assert_eq!(s.peek(), Some(&6));
        let pop_result = s.pop().unwrap(); // should not break
        s = pop_result.1;
        assert_eq!(s.peek(), Some(&1));
        assert_eq!(pop_result.0, 6);
    }

    #[test]
    fn test_list_macro() {
        let l: List<i32> = list!(1i32, 2i32, 3i32);
        assert_eq!(l.to_string(), "(1, (2, (3, nil)))")
    }

    #[test]
    fn test_list_iter() {
        let l: List<isize> = list!(1,2,3,4,5,6);
        let mut string = String::new();
        for item in l.iter() {
            string.push_str((item.to_string() + ", ").as_slice());
        }
        assert_eq!(string.as_slice(), "1, 2, 3, 4, 5, 6, ")
    }

}
<commit_msg>Apparently I never wrote tests for list indexing<commit_after>pub use svm::slist::List::{Cons,Nil};
use std::fmt;
use std::ops::Index;

/// Convenience macro for making lists.
///
/// # Example:
///
/// ```
/// # #[macro_use] extern crate seax_svm;
/// # use seax_svm::svm::slist;
/// # use seax_svm::svm::slist::List::{Cons, Nil};
/// # fn main () {
/// assert_eq!(
///     list!(1i32, 2i32, 3i32),
///     Cons(1i32, Box::new(Cons(2i32, Box::new(Cons(3i32, Box::new(Nil))))))
///     );
/// # }
/// ```
#[macro_export]
macro_rules! list(
    ( $e:expr, $($rest:expr),+ ) => ( Cons($e, Box::new(list!( $( $rest ),+ )) ));
    ( $e:expr ) => ( Cons($e, Box::new(Nil)) );
    () => ( @Empty )
);

/// Common functions for an immutable Stack abstract data type.
pub trait Stack<T> {

    /// Push an item to the top of the stack, returning a new stack
    fn push(self, item : T) -> Self;

    /// Pop the top element of the stack. Returns an Option on a T and
    /// a new Stack<T> to replace this.
    fn pop(self)            -> Option<(T, Self)>;

    /// Peek at the top item of the stack.
    ///
    /// Returns Some<T> if there is an item on top of the stack,
    /// and None if the stack is empty.
    fn peek(&self)          -> Option<&T>;

    /// Returns an empty stack.
    fn empty()              -> Self;
}

/// Stack implementation using a cons list
impl<T> Stack<T> for List<T> {

    /// Push an item to the top of the stack, returning a new stack.
    ///
    /// # Examples:
    /// ```
    /// use seax_svm::svm::slist::{List,Stack};
    ///
    /// let mut s: List<isize> = Stack::empty();
    /// assert_eq!(s.peek(), None);
    /// s = s.push(1);
    /// assert_eq!(s.peek(), Some(&1));
    /// s = s.push(6);
    /// assert_eq!(s.peek(), Some(&6));
    /// ```
    fn push(self, item: T) -> List<T> {
        Cons(item, box self)
    }

    /// Pop the top element of the stack.
    ///
    /// Pop the top element of the stack. Returns an
    /// `Option<(T,List<T>)>` containing the top element and a new
    /// `List<T>` with that item removed, or `None` if the stack is
    /// empty.
    ///
    /// # Examples:
    /// ```
    /// # use seax_svm::svm::slist::{List,Stack};
    ///
    /// let mut s: List<isize> = Stack::empty();
    /// s = s.push(2);
    /// s = s.push(1);
    /// let pop_result = s.pop().unwrap();
    /// s = pop_result.1;
    /// assert_eq!(s.peek(), Some(&2));
    /// assert_eq!(pop_result.0, 1);
    /// ```
    fn pop(self) -> Option<(T,List<T>)> {
        match self {
            Cons(item, new_self)    => Some((item, *new_self)),
            Nil                     => None
        }
    }

    fn empty() -> List<T> {
        Nil
    }

    /// Peek at the top element of the stack.
    ///
    /// Peek at the top element of the stack. Returns an `Option<&T>`
    /// with a borrowed pointer to the top element, or `None` if the
    /// stack is empty.
    ///
    /// # Examples:
    /// ```
    /// # use seax_svm::svm::slist::{List,Stack};
    ///
    /// let mut s: List<isize> = Stack::empty();
    /// s = s.push(2);
    /// s = s.push(1);
    /// let pop_result = s.pop().unwrap();
    /// s = pop_result.1;
    /// assert_eq!(s.peek(), Some(&2));
    /// assert_eq!(pop_result.0, 1);
    /// ```
    fn peek(&self) -> Option<&T> {
        match self {
            &Nil => None,
            &Cons(ref it,_) => Some(it)
        }
    }

}

/// Singly-linked cons list.
///
/// This is used internally to represent list primitives in the
/// machine.
#[derive(PartialEq,Clone,Debug)]
pub enum List<T> {
    /// Cons cell containing a `T` and a link to the tail
    Cons(T, Box<List<T>>),
    /// The empty list.
    Nil,
}

/// Public implementation for List.
impl<T> List<T> {

    /// Creates a new empty list
    pub fn new() -> List<T> {
        Nil
    }

    /// Prepends the given item to the list.
    ///
    /// Returns the list containing the new  head item.
    /// This is an O(1) operation.
    pub fn prepend(self, it: T) -> List<T> {
        Cons(it, box self)
    }

    /// Appends an item to the end of the list.
    ///
    /// This is an O(n) operation.
    pub fn append(self, it: T) {
        unimplemented!()
    }

    /// Returns the length of the list.
    pub fn length (&self) -> usize {
        match *self {
            Cons(_, ref tail) => 1 + tail.length(),
            Nil => 0
        }
    }

    /// Provide a forward iterator
    #[inline]
    pub fn iter<'a>(&'a self) -> ListIterator<'a, T> {
        ListIterator{current: self}
    }
}

impl<'a, T> fmt::Display for List<T> where T: fmt::Display{

    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // TODO: replace toString with this
        match *self {
            Cons(ref head, ref tail) => write!(f, "({}, {})", head, tail),
            Nil => write!(f,"nil")
        }
    }
}

/// Wraps a List<T> to allow it to be used as an Iterator<T>
pub struct ListIterator<'a, T:'a> {
    current: &'a List<T>
}

/// Implementation of Iterator for List. This allows iteration by
/// link hopping.
impl<'a, T> Iterator for ListIterator<'a, T> {
    type Item = &'a T;

    /// Get the next element from the list.
    ///
    /// Get the next element from the list. Returns a `Some<T>`, or `Nil`
    /// if at the end of the list.
    ///
    /// # Examples:
    /// ```
    /// # #[macro_use] extern crate seax_svm;
    /// # use seax_svm::svm::slist;
    /// # use seax_svm::svm::slist::List;
    /// # use seax_svm::svm::slist::List::{Cons, Nil};
    /// # fn main () {
    /// let list = list!(1,2,3);
    /// let mut iter = list.iter();
    /// assert_eq!(iter.next().unwrap(), &1);
    /// assert_eq!(iter.next().unwrap(), &2);
    /// assert_eq!(iter.next().unwrap(), &3);
    /// # }
    /// ```
    /// ```
    /// # #[macro_use] extern crate seax_svm;
    /// # use seax_svm::svm::slist;
    /// # use seax_svm::svm::slist::List;
    /// # use seax_svm::svm::slist::List::{Cons, Nil};
    /// # fn main () {
    /// let l: List<isize> = list!(1,2,3,4,5,6);
    /// let mut string = String::new();
    /// for item in l.iter() {
    ///     string.push_str((item.to_string() + ", ").as_slice());
    /// }
    /// assert_eq!(string.as_slice(), "1, 2, 3, 4, 5, 6, ")
    /// # }
    /// ```
    fn next(&mut self) -> Option<&'a T> {
        match self.current {
            &Cons(ref head, box ref tail) => { self.current = tail; Some(head) },
            &Nil => None
        }
    }
}

impl<'a, T> ExactSizeIterator for ListIterator<'a, T> {
    fn len(&self) -> usize {
        self.current.length()
    }
}
/// Implementation of indexing for `List<T>`.
///
/// # Examples:
/// ```
/// # #[macro_use] extern crate seax_svm;
/// # use seax_svm::svm::slist;
/// # use seax_svm::svm::slist::List;
/// # use seax_svm::svm::slist::List::{Cons, Nil};
/// # fn main () {
/// let list = list!(1,2,3,4,5,6);
/// assert_eq!(list[1us], 1);
/// # }
/// ```
impl<T> Index<usize> for List<T> {
    type Output = T;

    fn index<'a>(&'a self, _index: &usize) -> &'a T {
        let mut it = self.iter();
        println!("debug, in index, length {}", _index);
        for _ in 0..*_index-1 {
            it.next();
        }
        it.next().unwrap()
    }
}
/// Implementation of indexing for `List<T>`.
///
/// # Examples:
/// ```
/// # #[macro_use] extern crate seax_svm;
/// # use seax_svm::svm::slist;
/// # use seax_svm::svm::slist::List;
/// # use seax_svm::svm::slist::List::{Cons, Nil};
/// # fn main () {
/// let list = list!(1,2,3,4,5,6);
/// assert_eq!(list[1is], 1);
/// # }
/// ```
impl<T> Index<isize> for List<T> {
    type Output = T;

    fn index<'a>(&'a self, _index: &isize) -> &'a T {
        let mut it = self.iter();
        for _ in 0..*_index-1 {
            it.next();
        }
        it.next().unwrap()
    }
}

#[cfg(test)]
mod tests {
    use super::{List, Stack};
    use super::List::{Cons,Nil};

    #[test]
    fn test_list_length() {
        let full_list: List<i32> = list!(1i32, 2i32, 3i32);
        let empty_list: List<i32> = List::new();
        assert_eq!(full_list.length(), 3);
        assert_eq!(empty_list.length(), 0);
    }

    #[test]
    fn test_list_to_string() {
        let l: List<i32> = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
        assert_eq!(l.to_string(), "(1, (2, (3, nil)))");
    }

    #[test]
    fn test_stack_length() {
        let full_stack: List<i32> = list!(1i32, 2i32, 3i32);
        let empty_stack: List<i32> = Stack::empty();
        assert_eq!(full_stack.length(), 3);
        assert_eq!(empty_stack.length(), 0);
    }

    #[test]
    fn test_stack_peek() {
        let full_stack: List<i32> = list!(1i32, 2i32, 3i32);
        let empty_stack: List<i32> = Stack::empty();
        assert_eq!(full_stack.peek(), Some(&1));
        assert_eq!(empty_stack.peek(), None);
    }

    #[test]
    fn test_stack_push() {
        let mut s: List<i32> = Stack::empty();
        assert_eq!(s.peek(), None);
        s = s.push(1);
        assert_eq!(s.peek(), Some(&1));
        s = s.push(6);
        assert_eq!(s.peek(), Some(&6));
    }

    #[test]
    fn test_stack_pop() {
        let mut s: List<i32> = Stack::empty();
        assert_eq!(s.peek(), None);
        s = s.push(1);
        assert_eq!(s.peek(), Some(&1));
        s = s.push(6);
        assert_eq!(s.peek(), Some(&6));
        let pop_result = s.pop().unwrap(); // should not break
        s = pop_result.1;
        assert_eq!(s.peek(), Some(&1));
        assert_eq!(pop_result.0, 6);
    }

    #[test]
    fn test_list_indexing() {
        let l: List<int> = list!(1,2,3,4,5,6);
        assert_eq!(l[0us],1);
        assert_eq!(l[1us],2);
        assert_eq!(l[2us],3);
        assert_eq!(l[3us],4);
        assert_eq!(l[4us],5);
        assert_eq!(l[5us],6);
    }

    #[test]
    fn test_list_macro() {
        let l: List<i32> = list!(1i32, 2i32, 3i32);
        assert_eq!(l.to_string(), "(1, (2, (3, nil)))")
    }

    #[test]
    fn test_list_iter() {
        let l: List<isize> = list!(1,2,3,4,5,6);
        let mut string = String::new();
        for item in l.iter() {
            string.push_str((item.to_string() + ", ").as_slice());
        }
        assert_eq!(string.as_slice(), "1, 2, 3, 4, 5, 6, ")
    }

}
<|endoftext|>


<commit_before>//! Support for patterns of arbitrary element types.
use std;
use std::marker::MarkerTrait;

mod walk;
use self::walk::{action,Action,Walkable,Walker};

/// An iterator that produces its input item exactly once.
struct Once<'a,T: 'a>(Option<&'a T>);

impl<'a,T> Once<'a,T> {
    fn new(obj: &'a T) -> Once<'a,T> {
        Once(Some(obj))
    }
}

impl<'a,T> Iterator for Once<'a,T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<&'a T> {
        let out = self.0;
        self.0 = None;
        out
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        match self.0 {
            Some(..) => (1, Some(1)),
            None => (0, Some(0))
        }
    }
}

/// A pattern's first set is the set of elements that may begin a sequence
/// matching that pattern.
trait FirstSet: MarkerTrait {}
/// The atomic first set is like the first set above, but yields only the
/// atomic values within the set.
trait AtomicFirstSet: MarkerTrait {}

/// Provides a method to determine whether a pattern is "nullable", i.e., can
/// match an empty sequence.
pub trait Nullable {
    /// Check if the token is nullable.
    fn is_nullable(&self) -> bool { false }
}

/// A component in a pattern.  Each element is either an atomic value, or
/// a Pattern trait object.
pub enum Element<T> {
    Atom(T),
    Pattern(Box<Pattern<T>>)
}

/// Interface for descriptions of syntactic patterns.
pub trait Pattern<T>: Walkable<PatternWalk::FirstSet,Element> + Walkable<PatternWalk::AtomicFirstSet,T> + Nullable {}

impl<'a,T> Nullable for Element<T> {
    fn is_nullable(&self) -> bool {
        match *self {
            Element::Atom(..) => false,
            Element::Pattern(ref pat) => pat.is_nullable(),
        }
    }
}

/// A sequence of atoms or subpatterns.
struct Sequence<T> {
    elements: Vec<Element<T>>
}

impl<'a,T: 'a> Walkable<AtomicFirstSet,&'a T> for Sequence<T> {
    type BaseIterator = std::slice::Iter<'a,Element<T>>;

    #[inline(always)]
    fn iter(&self) -> <Self as Walkable<AtomicFirstSet,&T>>::BaseIterator { self.elements.iter() }

    fn action<'b>(&self, element: &'b Element<T>) -> (Option<&T>, u8) {
        match *element {
            Element::Atom(..) =>
                Action{yield_value: Some(element),
                       recurse_on: None,
                       flags: action::TERMINATE},
            Element::Pattern(ref pat) =>
                Action{yield_value: None,
                       recurse_on: Some(element),
                       flags: if pat.is_nullable() { 0 } else { action::TERMINATE }}
        }
    }
}

impl<'a,T: 'a> Walkable<FirstSet,&'a Element<T>> for Sequence<T> {
    type BaseIterator = std::slice::Iter<'a,Element<T>>;

    #[inline(always)]
    fn iter(&self) -> <Self as Walkable<FirstSet,&Element<T>>>::BaseIterator { self.elements.iter() }

    #[inline(always)]
    fn action<'b>(&self, element: &'b Element<T>) -> (Option<&Element<T>>, u8) {
        match *element {
            Element::Atom(..) =>
                Action{yield_value: Some(element),
                       recurse_on: None,
                       flags: action::TERMINATE},
            Element::Pattern(ref pat) =>
                Action{yield_value: Some(element),
                       recurse_on: Some(element),
                       flags: if pat.is_nullable() { 0 } else { action::TERMINATE }}
        }
    }
}

impl<T> Nullable for Sequence<T> {
    fn is_nullable(&self) -> bool {
        if self.elements.is_empty() { true }
        else {
            for elt in self.elements.iter() {
                match *elt {
                    Element::Atom(..) => return false,
                    Element::Pattern(pat) => if ! pat.is_nullable() { return false; }
                }
            }
            true
        }
    }
}
<commit_msg>pattern: another change missed in @8b643d5<commit_after>//! Support for patterns of arbitrary element types.
use std;
use std::marker::MarkerTrait;

mod walk;
use self::walk::{action,Action,Walkable,Walker};

/// An iterator that produces its input item exactly once.
struct Once<'a,T: 'a>(Option<&'a T>);

impl<'a,T> Once<'a,T> {
    fn new(obj: &'a T) -> Once<'a,T> {
        Once(Some(obj))
    }
}

impl<'a,T> Iterator for Once<'a,T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<&'a T> {
        let out = self.0;
        self.0 = None;
        out
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        match self.0 {
            Some(..) => (1, Some(1)),
            None => (0, Some(0))
        }
    }
}

/// Interface for descriptions of syntactic patterns.
pub trait Pattern<T>: Walkable<FirstSet,Element<T>> + Walkable<AtomicFirstSet,T> + Nullable {}

/// A pattern's first set is the set of elements that may begin a sequence
/// matching that pattern.
trait FirstSet: MarkerTrait {}
/// The atomic first set is like the first set above, but yields only the
/// atomic values within the set.
trait AtomicFirstSet: MarkerTrait {}

/// Provides a method to determine whether a pattern is "nullable", i.e., can
/// match an empty sequence.
pub trait Nullable {
    /// Check if the token is nullable.
    fn is_nullable(&self) -> bool { false }
}

/// A component in a pattern.  Each element is either an atomic value, or
/// a Pattern trait object.
pub enum Element<T> {
    Atom(T),
    Pattern(Box<Pattern<T>>)
}

impl<'a,T> Nullable for Element<T> {
    fn is_nullable(&self) -> bool {
        match *self {
            Element::Atom(..) => false,
            Element::Pattern(ref pat) => pat.is_nullable(),
        }
    }
}

/// A sequence of atoms or subpatterns.
struct Sequence<T> {
    elements: Vec<Element<T>>
}

impl<'a,T: 'a> Walkable<AtomicFirstSet,&'a T> for Sequence<T> {
    type BaseIterator = std::slice::Iter<'a,Element<T>>;

    #[inline(always)]
    fn iter(&self) -> <Self as Walkable<AtomicFirstSet,&T>>::BaseIterator { self.elements.iter() }

    fn action<'b>(&self, element: &'b Element<T>) -> (Option<&T>, u8) {
        match *element {
            Element::Atom(..) =>
                Action{yield_value: Some(element),
                       recurse_on: None,
                       flags: action::TERMINATE},
            Element::Pattern(ref pat) =>
                Action{yield_value: None,
                       recurse_on: Some(element),
                       flags: if pat.is_nullable() { 0 } else { action::TERMINATE }}
        }
    }
}

impl<'a,T: 'a> Walkable<FirstSet,&'a Element<T>> for Sequence<T> {
    type BaseIterator = std::slice::Iter<'a,Element<T>>;

    #[inline(always)]
    fn iter(&self) -> <Self as Walkable<FirstSet,&Element<T>>>::BaseIterator { self.elements.iter() }

    #[inline(always)]
    fn action<'b>(&self, element: &'b Element<T>) -> (Option<&Element<T>>, u8) {
        match *element {
            Element::Atom(..) =>
                Action{yield_value: Some(element),
                       recurse_on: None,
                       flags: action::TERMINATE},
            Element::Pattern(ref pat) =>
                Action{yield_value: Some(element),
                       recurse_on: Some(element),
                       flags: if pat.is_nullable() { 0 } else { action::TERMINATE }}
        }
    }
}

impl<T> Nullable for Sequence<T> {
    fn is_nullable(&self) -> bool {
        if self.elements.is_empty() { true }
        else {
            for elt in self.elements.iter() {
                match *elt {
                    Element::Atom(..) => return false,
                    Element::Pattern(pat) => if ! pat.is_nullable() { return false; }
                }
            }
            true
        }
    }
}
<|endoftext|>