<commit_before>mod util;

use ast::{self, SourceMap};
use core;
use typeck::{self, TyCtxt};
use self::util::to_qualified_name;

use std::collections::{HashMap, HashSet};
use std::path::{Path, PathBuf};

#[derive(Debug)]
pub enum Error {
    UnexpectedQualifiedName,
    UnknownVariable(ast::Name),
    TypeCk(typeck::Error),
    InvalidImport,
    Many(Vec<Error>),
}

impl From<typeck::Error> for Error {
    fn from(err: typeck::Error) -> Error {
        Error::TypeCk(err)
    }
}
pub struct ElabCx {
    module: ast::Module,

    /// The set of declared constructor names in scope
    /// we need this to differentiate between a name
    /// binding or null-ary constructor in pattern
    /// matching.
    constructors: HashSet<ast::Name>,
    globals: HashMap<ast::Name, core::Name>,
    metavar_counter: usize,
    pub ty_cx: TyCtxt,
}

impl ElabCx {
    pub fn from_module(module: ast::Module, source_map: SourceMap) -> ElabCx {
        // Elaboration relies on type checking, so first we setup a typing context to use
        // while elaborating the program. We will run the type checker in inference mode
        // to setup constraints, and then we will solve the constraints, and check the
        // term again.
        let mut ty_cx = TyCtxt::empty();
        ty_cx.source_map = source_map;

        ElabCx {
            module: module,
            constructors: HashSet::new(),
            globals: HashMap::new(),
            ty_cx: ty_cx,
        }
    }

    pub fn elaborate_module<P: AsRef<Path>>(&mut self, path: P) -> Result<core::Module, Error> {
        let ecx = self;
        let module_name = ecx.module.name.clone();

        let name = try!(ecx.elaborate_global_name(module_name));

        let mut errors = vec![];
        let mut defs = vec![];
        let mut imports = vec![];

        for def in ecx.module.items.clone() {
            match &def {
                &ast::Item::Data(ref d) => {
                    for ctor in &d.ctors {
                        ecx.constructors.insert(ctor.0.clone());
                    }
                }
                &ast::Item::Import(ref n) => imports.push(try!(ecx.elaborate_import(n.clone()))),
                _ => {}
            }

            match ecx.elaborate_def(def) {
                Err(e) => errors.push(e),
                Ok(edef) => {
                    let edef = edef.map(|edef| {
                        match &edef {
                            &core::Item::Data(ref d) => ecx.ty_cx.declare_datatype(d),
                            &core::Item::Fn(ref f) => ecx.ty_cx.declare_def(f),
                            &core::Item::Extern(ref e) => ecx.ty_cx.declare_extern(e),
                        }
                        edef
                    });

                    match edef {
                        None => {}
                        Some(edef) => defs.push(edef),
                    }
                }
            }
        }

        if errors.len() != 0 {
            Err(Error::Many(errors))
        } else {
            let module = core::Module {
                file_name: path.as_ref().to_owned(),
                name: name,
                defs: defs,
                imports: imports,
            };

            try!(ecx.ty_cx.type_check_module(&module));

            Ok(module)
        }
    }

    pub fn elaborate_import(&mut self, name: ast::Name) -> Result<core::Name, Error> {
        let core_name = to_qualified_name(name);
        let main_file = PathBuf::from(self.ty_cx.source_map.file_name.clone());
        let load_path = main_file.parent().unwrap();
        try!(self.ty_cx.load_import(load_path, &core_name));
        Ok(core_name)
    }

    pub fn elaborate_def(&mut self, def: ast::Item) -> Result<Option<core::Item>, Error> {
        debug!("elaborate_def: def={:?}", def);

        match def {
            ast::Item::Data(d) => {
                let edata = core::Item::Data(try!(self.elaborate_data(d)));
                Ok(Some(edata))
            }
            ast::Item::Fn(f) => {
                let efn = core::Item::Fn(try!(self.elaborate_fn(f)));
                debug!("elaborate_def: fn={}", efn);
                Ok(Some(efn))
            }
            ast::Item::Extern(e) => {
                let ext = core::Item::Extern(try!(self.elaborate_extern(e)));
                Ok(Some(ext))
            }
            ast::Item::Comment(_) |
            ast::Item::Import(_) => Ok(None),
        }
    }

    fn elaborate_data(&mut self, data: ast::Data) -> Result<core::Data, Error> {
        let ast_rec_name = data.name.in_scope("rec".to_string()).unwrap();
        let ty_name = try!(self.elaborate_global_name(data.name));

        // Pre-declare the recursor name for the time being.
        self.globals.insert(
            ast_rec_name,
            ty_name.in_scope("rec".to_string()).unwrap());

        let mut lcx = LocalElabCx::from_elab_cx(self);

        let data_ctors = data.ctors;
        let data_ty = data.ty;

        let (ctors, ty) = try!(lcx.enter_scope(data.parameters.clone(), move |lcx, params| {
            let mut ctors = Vec::new();
            for ctor in data_ctors.into_iter() {
                let ector = try!(lcx.elaborate_ctor(&params, ctor));
                ctors.push(ector);
            }

            let ty = core::Term::abstract_pi(
                params,
                try!(lcx.elaborate_term(data_ty)));

            Ok((ctors, ty))
        }));

        Ok(core::Data {
            span: data.span,
            name: ty_name,
            ty: ty,
            ctors: ctors,
        })
    }

    fn elaborate_fn(&mut self, fun: ast::Function) -> Result<core::Function, Error> {
        let mut lcx = LocalElabCx::from_elab_cx(self);

        lcx.enter_scope(fun.args.clone(), move |lcx, args| {
            let name = try!(lcx.cx.elaborate_global_name(fun.name));
            let ty = try!(lcx.elaborate_term(fun.ty.clone()));
            let ebody = try!(lcx.elaborate_term(fun.body));

            debug!("elaborate_fn: ty={} body={}", ty, ebody);

            Ok(core::Function {
                name: name,
                args: args.clone(),
                // We compute the full type of the function here
                // by taking the return type and abstracting
                // over the arguments.
                ret_ty: core::Term::abstract_pi(args.clone(), ty),
                // We construct a lambda representing the body
                // with all of the function's parameters abstracted.
                body: core::Term::abstract_lambda(args, ebody),
            })
        })
    }

    fn elaborate_extern(&mut self, ext: ast::Extern) -> Result<core::Extern, Error> {
        let ast::Extern { span, name, term } = ext;
        Ok(core::Extern {
            span: span,
            name: try!(self.elaborate_global_name(name)),
            term: try!(LocalElabCx::from_elab_cx(self).elaborate_term(term)),
        })
    }

    fn elaborate_global_name(&mut self, n: ast::Name) -> Result<core::Name, Error> {
        match n.repr.clone() {
            ast::NameKind::Qualified(_) => Err(Error::UnexpectedQualifiedName),
            ast::NameKind::Unqualified(name) => {
                let qn = core::Name::Qual {
                    span: n.span,
                    components: vec![name],
                };

                self.globals.insert(n.clone(), qn.clone());

                Ok(qn)
            }
        }
    }

    fn meta(&mut self, ty: Term) -> Result<core::Name, Error> {
        let meta_no = self.metavar_counter;
        let meta = core::Name::Meta {
            number: meta_no,
            ty: Box::new(ty),
        };
        self.metavar_counter += 1;
        Ok(meta)
    }
}

pub struct LocalElabCx<'ecx> {
    cx: &'ecx mut ElabCx,
    locals: HashMap<ast::Name, core::Name>,
}

impl<'ecx> LocalElabCx<'ecx> {
    pub fn from_elab_cx(ecx: &'ecx mut ElabCx) -> LocalElabCx<'ecx> {
        LocalElabCx {
            cx: ecx,
            locals: HashMap::new(),
            metavar_counter: 0,
        }
    }

    fn enter_scope<F, R>(&mut self,
                         binders: Vec<(ast::Name, ast::Term)>,
                         body: F)
                         -> Result<R, Error>
        where F: FnOnce(&mut LocalElabCx, Vec<core::Name>) -> Result<R, Error>
    {
        let mut locals = vec![];

        let old_context = self.locals.clone();

        for (name, t) in binders {
            let repr = match name.clone().repr {
                ast::NameKind::Qualified(..) => panic!(),
                ast::NameKind::Unqualified(s) => s,
            };

            let eterm = try!(self.elaborate_term(t));
            let local = self.cx.ty_cx.local_with_repr(repr, eterm.clone());

            self.locals.insert(name, local.clone());
            locals.push(local);
        }

        let result = try!(body(self, locals));

        self.locals = old_context;

        Ok(result)
    }

    fn elaborate_ctor(&mut self,
                      parameters: &Vec<core::Name>,
                      ctor: ast::Constructor)
                      -> Result<(core::Name, core::Term), Error> {

        let ename = try!(self.cx.elaborate_global_name(ctor.0));

        let ety = try!(self.elaborate_term(ctor.1));
        let ety = core::Term::abstract_pi(parameters.clone(), ety);

        Ok((ename, ety))
    }

    pub fn elaborate_term(&mut self, term: ast::Term) -> Result<core::Term, Error> {
        debug!("elaborate_term: term={:?}", term);

        match term {
            ast::Term::Literal { span, lit } => {
                Ok(core::Term::Literal {
                    span: span,
                    lit: self.elaborate_literal(lit),
                })
            }
            ast::Term::Var { name, .. } => {
                Ok(core::Term::Var { name: try!(self.elaborate_name(name)) })
            }
            ast::Term::Match { .. } => panic!("match elaboration is currently disabled"),
            ast::Term::App { fun, arg, span } => {
                let efun = try!(self.elaborate_term(*fun));
                let earg = try!(self.elaborate_term(*arg));

                Ok(core::Term::App {
                    span: span,
                    fun: Box::new(efun),
                    arg: Box::new(earg),
                })
            }
            ast::Term::Forall { name, ty, term, .. } => {
                self.enter_scope(vec![(name.clone(), *ty)], move |lcx, locals| {
                    let term = try!(lcx.elaborate_term(*term));
                    Ok(core::Term::abstract_pi(locals, term))
                })
            }
            ast::Term::Metavar { .. } => panic!("can't elaborate meta-variables"),
            ast::Term::Lambda { args, body, .. } => {
                self.enter_scope(args, move |lcx, locals| {
                    let ebody = try!(lcx.elaborate_term(*body));
                    Ok(core::Term::abstract_lambda(locals, ebody))
                })
            }
            ast::Term::Let { .. } => panic!("can't elaborate let-bindings"),
            ast::Term::Type => Ok(core::Term::Type),
        }
    }

    fn elaborate_literal(&self, lit: ast::Literal) -> core::Literal {
        match lit {
            ast::Literal::Unit => core::Literal::Unit,
            ast::Literal::Int(i) => core::Literal::Int(i),
        }
    }

    fn elaborate_name(&self, name: ast::Name) -> Result<core::Name, Error> {
        debug!("elaborate_name: name={}", name);

        // It is most likely to be a local
        match self.locals.get(&name) {
            // A global in the current module
            None => {
                match self.cx.globals.get(&name) {
                    // If it isn't a global we are going to see if the name has already been
                    // loading into the type context, if not this is an error.
                    None => {
                        let core_name = to_qualified_name(name.clone());
                        if self.cx.ty_cx.in_scope(&core_name) {
                            Ok(core_name)
                        } else {
                            Err(Error::UnknownVariable(name.clone()))
                        }
                    }
                    Some(nn) => Ok(nn.clone()),
                }
            }
            Some(local) => Ok(local.clone()),
        }
    }
}
<commit_msg>Fix compilation error<commit_after>mod util;

use ast::{self, SourceMap};
use core;
use typeck::{self, TyCtxt};
use self::util::to_qualified_name;

use std::collections::{HashMap, HashSet};
use std::path::{Path, PathBuf};

#[derive(Debug)]
pub enum Error {
    UnexpectedQualifiedName,
    UnknownVariable(ast::Name),
    TypeCk(typeck::Error),
    InvalidImport,
    Many(Vec<Error>),
}

impl From<typeck::Error> for Error {
    fn from(err: typeck::Error) -> Error {
        Error::TypeCk(err)
    }
}
pub struct ElabCx {
    module: ast::Module,

    /// The set of declared constructor names in scope
    /// we need this to differentiate between a name
    /// binding or null-ary constructor in pattern
    /// matching.
    constructors: HashSet<ast::Name>,
    globals: HashMap<ast::Name, core::Name>,
    metavar_counter: usize,
    pub ty_cx: TyCtxt,
}

impl ElabCx {
    pub fn from_module(module: ast::Module, source_map: SourceMap) -> ElabCx {
        // Elaboration relies on type checking, so first we setup a typing context to use
        // while elaborating the program. We will run the type checker in inference mode
        // to setup constraints, and then we will solve the constraints, and check the
        // term again.
        let mut ty_cx = TyCtxt::empty();
        ty_cx.source_map = source_map;

        ElabCx {
            module: module,
            constructors: HashSet::new(),
            globals: HashMap::new(),
            metavar_counter: 0,
            ty_cx: ty_cx,
        }
    }

    pub fn elaborate_module<P: AsRef<Path>>(&mut self, path: P) -> Result<core::Module, Error> {
        let ecx = self;
        let module_name = ecx.module.name.clone();

        let name = try!(ecx.elaborate_global_name(module_name));

        let mut errors = vec![];
        let mut defs = vec![];
        let mut imports = vec![];

        for def in ecx.module.items.clone() {
            match &def {
                &ast::Item::Data(ref d) => {
                    for ctor in &d.ctors {
                        ecx.constructors.insert(ctor.0.clone());
                    }
                }
                &ast::Item::Import(ref n) => imports.push(try!(ecx.elaborate_import(n.clone()))),
                _ => {}
            }

            match ecx.elaborate_def(def) {
                Err(e) => errors.push(e),
                Ok(edef) => {
                    let edef = edef.map(|edef| {
                        match &edef {
                            &core::Item::Data(ref d) => ecx.ty_cx.declare_datatype(d),
                            &core::Item::Fn(ref f) => ecx.ty_cx.declare_def(f),
                            &core::Item::Extern(ref e) => ecx.ty_cx.declare_extern(e),
                        }
                        edef
                    });

                    match edef {
                        None => {}
                        Some(edef) => defs.push(edef),
                    }
                }
            }
        }

        if errors.len() != 0 {
            Err(Error::Many(errors))
        } else {
            let module = core::Module {
                file_name: path.as_ref().to_owned(),
                name: name,
                defs: defs,
                imports: imports,
            };

            try!(ecx.ty_cx.type_check_module(&module));

            Ok(module)
        }
    }

    pub fn elaborate_import(&mut self, name: ast::Name) -> Result<core::Name, Error> {
        let core_name = to_qualified_name(name);
        let main_file = PathBuf::from(self.ty_cx.source_map.file_name.clone());
        let load_path = main_file.parent().unwrap();
        try!(self.ty_cx.load_import(load_path, &core_name));
        Ok(core_name)
    }

    pub fn elaborate_def(&mut self, def: ast::Item) -> Result<Option<core::Item>, Error> {
        debug!("elaborate_def: def={:?}", def);

        match def {
            ast::Item::Data(d) => {
                let edata = core::Item::Data(try!(self.elaborate_data(d)));
                Ok(Some(edata))
            }
            ast::Item::Fn(f) => {
                let efn = core::Item::Fn(try!(self.elaborate_fn(f)));
                debug!("elaborate_def: fn={}", efn);
                Ok(Some(efn))
            }
            ast::Item::Extern(e) => {
                let ext = core::Item::Extern(try!(self.elaborate_extern(e)));
                Ok(Some(ext))
            }
            ast::Item::Comment(_) |
            ast::Item::Import(_) => Ok(None),
        }
    }

    fn elaborate_data(&mut self, data: ast::Data) -> Result<core::Data, Error> {
        let ast_rec_name = data.name.in_scope("rec".to_string()).unwrap();
        let ty_name = try!(self.elaborate_global_name(data.name));

        // Pre-declare the recursor name for the time being.
        self.globals.insert(
            ast_rec_name,
            ty_name.in_scope("rec".to_string()).unwrap());

        let mut lcx = LocalElabCx::from_elab_cx(self);

        let data_ctors = data.ctors;
        let data_ty = data.ty;

        let (ctors, ty) = try!(lcx.enter_scope(data.parameters.clone(), move |lcx, params| {
            let mut ctors = Vec::new();
            for ctor in data_ctors.into_iter() {
                let ector = try!(lcx.elaborate_ctor(&params, ctor));
                ctors.push(ector);
            }

            let ty = core::Term::abstract_pi(
                params,
                try!(lcx.elaborate_term(data_ty)));

            Ok((ctors, ty))
        }));

        Ok(core::Data {
            span: data.span,
            name: ty_name,
            ty: ty,
            ctors: ctors,
        })
    }

    fn elaborate_fn(&mut self, fun: ast::Function) -> Result<core::Function, Error> {
        let mut lcx = LocalElabCx::from_elab_cx(self);

        lcx.enter_scope(fun.args.clone(), move |lcx, args| {
            let name = try!(lcx.cx.elaborate_global_name(fun.name));
            let ty = try!(lcx.elaborate_term(fun.ty.clone()));
            let ebody = try!(lcx.elaborate_term(fun.body));

            debug!("elaborate_fn: ty={} body={}", ty, ebody);

            Ok(core::Function {
                name: name,
                args: args.clone(),
                // We compute the full type of the function here
                // by taking the return type and abstracting
                // over the arguments.
                ret_ty: core::Term::abstract_pi(args.clone(), ty),
                // We construct a lambda representing the body
                // with all of the function's parameters abstracted.
                body: core::Term::abstract_lambda(args, ebody),
            })
        })
    }

    fn elaborate_extern(&mut self, ext: ast::Extern) -> Result<core::Extern, Error> {
        let ast::Extern { span, name, term } = ext;
        Ok(core::Extern {
            span: span,
            name: try!(self.elaborate_global_name(name)),
            term: try!(LocalElabCx::from_elab_cx(self).elaborate_term(term)),
        })
    }

    fn elaborate_global_name(&mut self, n: ast::Name) -> Result<core::Name, Error> {
        match n.repr.clone() {
            ast::NameKind::Qualified(_) => Err(Error::UnexpectedQualifiedName),
            ast::NameKind::Unqualified(name) => {
                let qn = core::Name::Qual {
                    span: n.span,
                    components: vec![name],
                };

                self.globals.insert(n.clone(), qn.clone());

                Ok(qn)
            }
        }
    }

    fn meta(&mut self, ty: core::Term) -> Result<core::Name, Error> {
        let meta_no = self.metavar_counter;
        let meta = core::Name::Meta {
            number: meta_no,
            ty: Box::new(ty),
        };
        self.metavar_counter += 1;
        Ok(meta)
    }
}

pub struct LocalElabCx<'ecx> {
    cx: &'ecx mut ElabCx,
    locals: HashMap<ast::Name, core::Name>,
}

impl<'ecx> LocalElabCx<'ecx> {
    pub fn from_elab_cx(ecx: &'ecx mut ElabCx) -> LocalElabCx<'ecx> {
        LocalElabCx {
            cx: ecx,
            locals: HashMap::new(),
        }
    }

    fn enter_scope<F, R>(&mut self,
                         binders: Vec<(ast::Name, ast::Term)>,
                         body: F)
                         -> Result<R, Error>
        where F: FnOnce(&mut LocalElabCx, Vec<core::Name>) -> Result<R, Error>
    {
        let mut locals = vec![];

        let old_context = self.locals.clone();

        for (name, t) in binders {
            let repr = match name.clone().repr {
                ast::NameKind::Qualified(..) => panic!(),
                ast::NameKind::Unqualified(s) => s,
            };

            let eterm = try!(self.elaborate_term(t));
            let local = self.cx.ty_cx.local_with_repr(repr, eterm.clone());

            self.locals.insert(name, local.clone());
            locals.push(local);
        }

        let result = try!(body(self, locals));

        self.locals = old_context;

        Ok(result)
    }

    fn elaborate_ctor(&mut self,
                      parameters: &Vec<core::Name>,
                      ctor: ast::Constructor)
                      -> Result<(core::Name, core::Term), Error> {

        let ename = try!(self.cx.elaborate_global_name(ctor.0));

        let ety = try!(self.elaborate_term(ctor.1));
        let ety = core::Term::abstract_pi(parameters.clone(), ety);

        Ok((ename, ety))
    }

    pub fn elaborate_term(&mut self, term: ast::Term) -> Result<core::Term, Error> {
        debug!("elaborate_term: term={:?}", term);

        match term {
            ast::Term::Literal { span, lit } => {
                Ok(core::Term::Literal {
                    span: span,
                    lit: self.elaborate_literal(lit),
                })
            }
            ast::Term::Var { name, .. } => {
                Ok(core::Term::Var { name: try!(self.elaborate_name(name)) })
            }
            ast::Term::Match { .. } => panic!("match elaboration is currently disabled"),
            ast::Term::App { fun, arg, span } => {
                let efun = try!(self.elaborate_term(*fun));
                let earg = try!(self.elaborate_term(*arg));

                Ok(core::Term::App {
                    span: span,
                    fun: Box::new(efun),
                    arg: Box::new(earg),
                })
            }
            ast::Term::Forall { name, ty, term, .. } => {
                self.enter_scope(vec![(name.clone(), *ty)], move |lcx, locals| {
                    let term = try!(lcx.elaborate_term(*term));
                    Ok(core::Term::abstract_pi(locals, term))
                })
            }
            ast::Term::Metavar { .. } => panic!("can't elaborate meta-variables"),
            ast::Term::Lambda { args, body, .. } => {
                self.enter_scope(args, move |lcx, locals| {
                    let ebody = try!(lcx.elaborate_term(*body));
                    Ok(core::Term::abstract_lambda(locals, ebody))
                })
            }
            ast::Term::Let { .. } => panic!("can't elaborate let-bindings"),
            ast::Term::Type => Ok(core::Term::Type),
        }
    }

    fn elaborate_literal(&self, lit: ast::Literal) -> core::Literal {
        match lit {
            ast::Literal::Unit => core::Literal::Unit,
            ast::Literal::Int(i) => core::Literal::Int(i),
        }
    }

    fn elaborate_name(&self, name: ast::Name) -> Result<core::Name, Error> {
        debug!("elaborate_name: name={}", name);

        // It is most likely to be a local
        match self.locals.get(&name) {
            // A global in the current module
            None => {
                match self.cx.globals.get(&name) {
                    // If it isn't a global we are going to see if the name has already been
                    // loading into the type context, if not this is an error.
                    None => {
                        let core_name = to_qualified_name(name.clone());
                        if self.cx.ty_cx.in_scope(&core_name) {
                            Ok(core_name)
                        } else {
                            Err(Error::UnknownVariable(name.clone()))
                        }
                    }
                    Some(nn) => Ok(nn.clone()),
                }
            }
            Some(local) => Ok(local.clone()),
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 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.

//! Types dealing with dynamic mutability

use clone::{Clone, DeepClone};
use cmp::Eq;
use ops::Drop;
use option::{None, Option, Some};
use cast;
use kinds::{marker, Pod};

/// A mutable memory location that admits only `Pod` data.
pub struct Cell<T> {
    priv value: T,
    priv marker1: marker::InvariantType<T>,
    priv marker2: marker::NoFreeze,
}

impl<T:Pod> Cell<T> {
    /// Creates a new `Cell` containing the given value.
    pub fn new(value: T) -> Cell<T> {
        Cell {
            value: value,
            marker1: marker::InvariantType::<T>,
            marker2: marker::NoFreeze,
        }
    }

    /// Returns a copy of the contained value.
    #[inline]
    pub fn get(&self) -> T {
        self.value
    }

    /// Sets the contained value.
    #[inline]
    pub fn set(&self, value: T) {
        unsafe {
            *cast::transmute_mut(&self.value) = value
        }
    }
}

impl<T:Pod> Clone for Cell<T> {
    fn clone(&self) -> Cell<T> {
        Cell::new(self.get())
    }
}

/// A mutable memory location with dynamically checked borrow rules
pub struct RefCell<T> {
    priv value: T,
    priv borrow: BorrowFlag,
    priv marker1: marker::InvariantType<T>,
    priv marker2: marker::NoFreeze,
    priv marker3: marker::NoPod,
}

// Values [1, MAX-1] represent the number of `Ref` active
// (will not outgrow its range since `uint` is the size of the address space)
type BorrowFlag = uint;
static UNUSED: BorrowFlag = 0;
static WRITING: BorrowFlag = -1;

impl<T> RefCell<T> {
    /// Create a new `RefCell` containing `value`
    pub fn new(value: T) -> RefCell<T> {
        RefCell {
            marker1: marker::InvariantType::<T>,
            marker2: marker::NoFreeze,
            marker3: marker::NoPod,
            value: value,
            borrow: UNUSED,
        }
    }

    /// Consumes the `RefCell`, returning the wrapped value.
    pub fn unwrap(self) -> T {
        assert!(self.borrow == UNUSED);
        self.value
    }

    unsafe fn as_mut<'a>(&'a self) -> &'a mut RefCell<T> {
        cast::transmute_mut(self)
    }

    /// Attempts to immutably borrow the wrapped value.
    ///
    /// The borrow lasts until the returned `Ref` exits scope. Multiple
    /// immutable borrows can be taken out at the same time.
    ///
    /// Returns `None` if the value is currently mutably borrowed.
    pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
        match self.borrow {
            WRITING => None,
            _ => {
                unsafe { self.as_mut().borrow += 1; }
                Some(Ref { parent: self })
            }
        }
    }

    /// Immutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `Ref` exits scope. Multiple
    /// immutable borrows can be taken out at the same time.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently mutably borrowed.
    pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
        match self.try_borrow() {
            Some(ptr) => ptr,
            None => fail!("RefCell<T> already mutably borrowed")
        }
    }

    /// Mutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `RefMut` exits scope. The value
    /// cannot be borrowed while this borrow is active.
    ///
    /// Returns `None` if the value is currently borrowed.
    pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
        match self.borrow {
            UNUSED => unsafe {
                let mut_self = self.as_mut();
                mut_self.borrow = WRITING;
                Some(RefMut { parent: mut_self })
            },
            _ => None
        }
    }

    /// Mutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `RefMut` exits scope. The value
    /// cannot be borrowed while this borrow is active.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently borrowed.
    pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
        match self.try_borrow_mut() {
            Some(ptr) => ptr,
            None => fail!("RefCell<T> already borrowed")
        }
    }

    /// Immutably borrows the wrapped value and applies `blk` to it.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently mutably borrowed.
    #[inline]
    pub fn with<U>(&self, blk: |&T| -> U) -> U {
        let ptr = self.borrow();
        blk(ptr.get())
    }

    /// Mutably borrows the wrapped value and applies `blk` to it.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently borrowed.
    #[inline]
    pub fn with_mut<U>(&self, blk: |&mut T| -> U) -> U {
        let mut ptr = self.borrow_mut();
        blk(ptr.get())
    }

    /// Sets the value, replacing what was there.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently borrowed.
    #[inline]
    pub fn set(&self, value: T) {
        let mut reference = self.borrow_mut();
        *reference.get() = value
    }
}

impl<T:Clone> RefCell<T> {
    /// Returns a copy of the contained value.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently mutably borrowed.
    #[inline]
    pub fn get(&self) -> T {
        let reference = self.borrow();
        (*reference.get()).clone()
    }
}

impl<T: Clone> Clone for RefCell<T> {
    fn clone(&self) -> RefCell<T> {
        let x = self.borrow();
        RefCell::new(x.get().clone())
    }
}

impl<T: DeepClone> DeepClone for RefCell<T> {
    fn deep_clone(&self) -> RefCell<T> {
        let x = self.borrow();
        RefCell::new(x.get().deep_clone())
    }
}

impl<T: Eq> Eq for RefCell<T> {
    fn eq(&self, other: &RefCell<T>) -> bool {
        let a = self.borrow();
        let b = other.borrow();
        a.get() == b.get()
    }
}

/// Wraps a borrowed reference to a value in a `RefCell` box.
pub struct Ref<'b, T> {
    priv parent: &'b RefCell<T>
}

#[unsafe_destructor]
impl<'b, T> Drop for Ref<'b, T> {
    fn drop(&mut self) {
        assert!(self.parent.borrow != WRITING && self.parent.borrow != UNUSED);
        unsafe { self.parent.as_mut().borrow -= 1; }
    }
}

impl<'b, T> Ref<'b, T> {
    /// Retrieve an immutable reference to the stored value.
    #[inline]
    pub fn get<'a>(&'a self) -> &'a T {
        &self.parent.value
    }
}

/// Wraps a mutable borrowed reference to a value in a `RefCell` box.
pub struct RefMut<'b, T> {
    priv parent: &'b mut RefCell<T>
}

#[unsafe_destructor]
impl<'b, T> Drop for RefMut<'b, T> {
    fn drop(&mut self) {
        assert!(self.parent.borrow == WRITING);
        self.parent.borrow = UNUSED;
    }
}

impl<'b, T> RefMut<'b, T> {
    /// Retrieve a mutable reference to the stored value.
    #[inline]
    pub fn get<'a>(&'a mut self) -> &'a mut T {
        &mut self.parent.value
    }
}

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

    #[test]
    fn smoketest_cell() {
        let x = Cell::new(10);
        assert_eq!(x.get(), 10);
        x.set(20);
        assert_eq!(x.get(), 20);

        let y = Cell::new((30, 40));
        assert_eq!(y.get(), (30, 40));
    }

    #[test]
    fn double_imm_borrow() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        x.borrow();
    }

    #[test]
    fn no_mut_then_imm_borrow() {
        let x = RefCell::new(0);
        let _b1 = x.borrow_mut();
        assert!(x.try_borrow().is_none());
    }

    #[test]
    fn no_imm_then_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    fn no_double_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow_mut();
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    fn imm_release_borrow_mut() {
        let x = RefCell::new(0);
        {
            let _b1 = x.borrow();
        }
        x.borrow_mut();
    }

    #[test]
    fn mut_release_borrow_mut() {
        let x = RefCell::new(0);
        {
            let _b1 = x.borrow_mut();
        }
        x.borrow();
    }

    #[test]
    fn double_borrow_single_release_no_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        {
            let _b2 = x.borrow();
        }
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    fn with_ok() {
        let x = RefCell::new(0);
        assert_eq!(1, x.with(|x| *x+1));
    }

    #[test]
    #[should_fail]
    fn mut_borrow_with() {
        let x = RefCell::new(0);
        let _b1 = x.borrow_mut();
        x.with(|x| *x+1);
    }

    #[test]
    fn borrow_with() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        assert_eq!(1, x.with(|x| *x+1));
    }

    #[test]
    fn with_mut_ok() {
        let x = RefCell::new(0);
        x.with_mut(|x| *x += 1);
        let b = x.borrow();
        assert_eq!(1, *b.get());
    }

    #[test]
    #[should_fail]
    fn borrow_with_mut() {
        let x = RefCell::new(0);
        let _b = x.borrow();
        x.with_mut(|x| *x += 1);
    }

    #[test]
    #[should_fail]
    fn discard_doesnt_unborrow() {
        let x = RefCell::new(0);
        let _b = x.borrow();
        let _ = _b;
        let _b = x.borrow_mut();
    }
}
<commit_msg>Implement Eq for Cell<T><commit_after>// Copyright 2012-2013 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.

//! Types dealing with dynamic mutability

use clone::{Clone, DeepClone};
use cmp::Eq;
use ops::Drop;
use option::{None, Option, Some};
use cast;
use kinds::{marker, Pod};

/// A mutable memory location that admits only `Pod` data.
pub struct Cell<T> {
    priv value: T,
    priv marker1: marker::InvariantType<T>,
    priv marker2: marker::NoFreeze,
}

impl<T:Pod> Cell<T> {
    /// Creates a new `Cell` containing the given value.
    pub fn new(value: T) -> Cell<T> {
        Cell {
            value: value,
            marker1: marker::InvariantType::<T>,
            marker2: marker::NoFreeze,
        }
    }

    /// Returns a copy of the contained value.
    #[inline]
    pub fn get(&self) -> T {
        self.value
    }

    /// Sets the contained value.
    #[inline]
    pub fn set(&self, value: T) {
        unsafe {
            *cast::transmute_mut(&self.value) = value
        }
    }
}

impl<T:Pod> Clone for Cell<T> {
    fn clone(&self) -> Cell<T> {
        Cell::new(self.get())
    }
}

impl<T:Eq + Pod> Eq for Cell<T> {
    fn eq(&self, other: &Cell<T>) -> bool {
        self.get() == other.get()
    }
}

/// A mutable memory location with dynamically checked borrow rules
pub struct RefCell<T> {
    priv value: T,
    priv borrow: BorrowFlag,
    priv marker1: marker::InvariantType<T>,
    priv marker2: marker::NoFreeze,
    priv marker3: marker::NoPod,
}

// Values [1, MAX-1] represent the number of `Ref` active
// (will not outgrow its range since `uint` is the size of the address space)
type BorrowFlag = uint;
static UNUSED: BorrowFlag = 0;
static WRITING: BorrowFlag = -1;

impl<T> RefCell<T> {
    /// Create a new `RefCell` containing `value`
    pub fn new(value: T) -> RefCell<T> {
        RefCell {
            marker1: marker::InvariantType::<T>,
            marker2: marker::NoFreeze,
            marker3: marker::NoPod,
            value: value,
            borrow: UNUSED,
        }
    }

    /// Consumes the `RefCell`, returning the wrapped value.
    pub fn unwrap(self) -> T {
        assert!(self.borrow == UNUSED);
        self.value
    }

    unsafe fn as_mut<'a>(&'a self) -> &'a mut RefCell<T> {
        cast::transmute_mut(self)
    }

    /// Attempts to immutably borrow the wrapped value.
    ///
    /// The borrow lasts until the returned `Ref` exits scope. Multiple
    /// immutable borrows can be taken out at the same time.
    ///
    /// Returns `None` if the value is currently mutably borrowed.
    pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
        match self.borrow {
            WRITING => None,
            _ => {
                unsafe { self.as_mut().borrow += 1; }
                Some(Ref { parent: self })
            }
        }
    }

    /// Immutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `Ref` exits scope. Multiple
    /// immutable borrows can be taken out at the same time.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently mutably borrowed.
    pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
        match self.try_borrow() {
            Some(ptr) => ptr,
            None => fail!("RefCell<T> already mutably borrowed")
        }
    }

    /// Mutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `RefMut` exits scope. The value
    /// cannot be borrowed while this borrow is active.
    ///
    /// Returns `None` if the value is currently borrowed.
    pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
        match self.borrow {
            UNUSED => unsafe {
                let mut_self = self.as_mut();
                mut_self.borrow = WRITING;
                Some(RefMut { parent: mut_self })
            },
            _ => None
        }
    }

    /// Mutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `RefMut` exits scope. The value
    /// cannot be borrowed while this borrow is active.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently borrowed.
    pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
        match self.try_borrow_mut() {
            Some(ptr) => ptr,
            None => fail!("RefCell<T> already borrowed")
        }
    }

    /// Immutably borrows the wrapped value and applies `blk` to it.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently mutably borrowed.
    #[inline]
    pub fn with<U>(&self, blk: |&T| -> U) -> U {
        let ptr = self.borrow();
        blk(ptr.get())
    }

    /// Mutably borrows the wrapped value and applies `blk` to it.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently borrowed.
    #[inline]
    pub fn with_mut<U>(&self, blk: |&mut T| -> U) -> U {
        let mut ptr = self.borrow_mut();
        blk(ptr.get())
    }

    /// Sets the value, replacing what was there.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently borrowed.
    #[inline]
    pub fn set(&self, value: T) {
        let mut reference = self.borrow_mut();
        *reference.get() = value
    }
}

impl<T:Clone> RefCell<T> {
    /// Returns a copy of the contained value.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently mutably borrowed.
    #[inline]
    pub fn get(&self) -> T {
        let reference = self.borrow();
        (*reference.get()).clone()
    }
}

impl<T: Clone> Clone for RefCell<T> {
    fn clone(&self) -> RefCell<T> {
        let x = self.borrow();
        RefCell::new(x.get().clone())
    }
}

impl<T: DeepClone> DeepClone for RefCell<T> {
    fn deep_clone(&self) -> RefCell<T> {
        let x = self.borrow();
        RefCell::new(x.get().deep_clone())
    }
}

impl<T: Eq> Eq for RefCell<T> {
    fn eq(&self, other: &RefCell<T>) -> bool {
        let a = self.borrow();
        let b = other.borrow();
        a.get() == b.get()
    }
}

/// Wraps a borrowed reference to a value in a `RefCell` box.
pub struct Ref<'b, T> {
    priv parent: &'b RefCell<T>
}

#[unsafe_destructor]
impl<'b, T> Drop for Ref<'b, T> {
    fn drop(&mut self) {
        assert!(self.parent.borrow != WRITING && self.parent.borrow != UNUSED);
        unsafe { self.parent.as_mut().borrow -= 1; }
    }
}

impl<'b, T> Ref<'b, T> {
    /// Retrieve an immutable reference to the stored value.
    #[inline]
    pub fn get<'a>(&'a self) -> &'a T {
        &self.parent.value
    }
}

/// Wraps a mutable borrowed reference to a value in a `RefCell` box.
pub struct RefMut<'b, T> {
    priv parent: &'b mut RefCell<T>
}

#[unsafe_destructor]
impl<'b, T> Drop for RefMut<'b, T> {
    fn drop(&mut self) {
        assert!(self.parent.borrow == WRITING);
        self.parent.borrow = UNUSED;
    }
}

impl<'b, T> RefMut<'b, T> {
    /// Retrieve a mutable reference to the stored value.
    #[inline]
    pub fn get<'a>(&'a mut self) -> &'a mut T {
        &mut self.parent.value
    }
}

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

    #[test]
    fn smoketest_cell() {
        let x = Cell::new(10);
        assert_eq!(x, Cell::new(10));
        assert_eq!(x.get(), 10);
        x.set(20);
        assert_eq!(x, Cell::new(20));
        assert_eq!(x.get(), 20);

        let y = Cell::new((30, 40));
        assert_eq!(y, Cell::new((30, 40)));
        assert_eq!(y.get(), (30, 40));
    }

    #[test]
    fn double_imm_borrow() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        x.borrow();
    }

    #[test]
    fn no_mut_then_imm_borrow() {
        let x = RefCell::new(0);
        let _b1 = x.borrow_mut();
        assert!(x.try_borrow().is_none());
    }

    #[test]
    fn no_imm_then_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    fn no_double_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow_mut();
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    fn imm_release_borrow_mut() {
        let x = RefCell::new(0);
        {
            let _b1 = x.borrow();
        }
        x.borrow_mut();
    }

    #[test]
    fn mut_release_borrow_mut() {
        let x = RefCell::new(0);
        {
            let _b1 = x.borrow_mut();
        }
        x.borrow();
    }

    #[test]
    fn double_borrow_single_release_no_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        {
            let _b2 = x.borrow();
        }
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    fn with_ok() {
        let x = RefCell::new(0);
        assert_eq!(1, x.with(|x| *x+1));
    }

    #[test]
    #[should_fail]
    fn mut_borrow_with() {
        let x = RefCell::new(0);
        let _b1 = x.borrow_mut();
        x.with(|x| *x+1);
    }

    #[test]
    fn borrow_with() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        assert_eq!(1, x.with(|x| *x+1));
    }

    #[test]
    fn with_mut_ok() {
        let x = RefCell::new(0);
        x.with_mut(|x| *x += 1);
        let b = x.borrow();
        assert_eq!(1, *b.get());
    }

    #[test]
    #[should_fail]
    fn borrow_with_mut() {
        let x = RefCell::new(0);
        let _b = x.borrow();
        x.with_mut(|x| *x += 1);
    }

    #[test]
    #[should_fail]
    fn discard_doesnt_unborrow() {
        let x = RefCell::new(0);
        let _b = x.borrow();
        let _ = _b;
        let _b = x.borrow_mut();
    }
}
<|endoftext|>


<commit_before>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Haitao Li <lihaitao@gmail.com>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

// spell-checker:ignore (ToDO) errno

#[macro_use]
extern crate uucore;

use clap::{crate_version, App, Arg};
use std::fs;
use std::io::{stdout, Write};
use std::path::{Path, PathBuf};
use uucore::display::Quotable;
use uucore::fs::{canonicalize, MissingHandling, ResolveMode};

const ABOUT: &str = "Print value of a symbolic link or canonical file name.";
const OPT_CANONICALIZE: &str = "canonicalize";
const OPT_CANONICALIZE_MISSING: &str = "canonicalize-missing";
const OPT_CANONICALIZE_EXISTING: &str = "canonicalize-existing";
const OPT_NO_NEWLINE: &str = "no-newline";
const OPT_QUIET: &str = "quiet";
const OPT_SILENT: &str = "silent";
const OPT_VERBOSE: &str = "verbose";
const OPT_ZERO: &str = "zero";

const ARG_FILES: &str = "files";

fn usage() -> String {
    format!("{0} [OPTION]... [FILE]...", uucore::execution_phrase())
}

pub fn uumain(args: impl uucore::Args) -> i32 {
    let usage = usage();
    let matches = uu_app().usage(&usage[..]).get_matches_from(args);

    let mut no_newline = matches.is_present(OPT_NO_NEWLINE);
    let use_zero = matches.is_present(OPT_ZERO);
    let silent = matches.is_present(OPT_SILENT) || matches.is_present(OPT_QUIET);
    let verbose = matches.is_present(OPT_VERBOSE);

    let res_mode = if matches.is_present(OPT_CANONICALIZE)
        || matches.is_present(OPT_CANONICALIZE_EXISTING)
        || matches.is_present(OPT_CANONICALIZE_MISSING)
    {
        ResolveMode::Logical
    } else {
        ResolveMode::None
    };

    let can_mode = if matches.is_present(OPT_CANONICALIZE_EXISTING) {
        MissingHandling::Existing
    } else if matches.is_present(OPT_CANONICALIZE_MISSING) {
        MissingHandling::Missing
    } else {
        MissingHandling::Normal
    };

    let files: Vec<String> = matches
        .values_of(ARG_FILES)
        .map(|v| v.map(ToString::to_string).collect())
        .unwrap_or_default();
    if files.is_empty() {
        crash!(
            1,
            "missing operand\nTry '{} --help' for more information",
            uucore::execution_phrase()
        );
    }

    if no_newline && files.len() > 1 && !silent {
        show_error!("ignoring --no-newline with multiple arguments");
        no_newline = false;
    }

    for f in &files {
        let p = PathBuf::from(f);
        if res_mode == ResolveMode::None {
            match fs::read_link(&p) {
                Ok(path) => show(&path, no_newline, use_zero),
                Err(err) => {
                    if verbose {
                        show_error!("{}: errno {}", f.maybe_quote(), err.raw_os_error().unwrap());
                    }
                    return 1;
                }
            }
        } else {
            match canonicalize(&p, can_mode, res_mode) {
                Ok(path) => show(&path, no_newline, use_zero),
                Err(err) => {
                    if verbose {
                        show_error!("{}: errno {}", f.maybe_quote(), err.raw_os_error().unwrap());
                    }
                    return 1;
                }
            }
        }
    }

    0
}

pub fn uu_app() -> App<'static, 'static> {
    App::new(uucore::util_name())
        .version(crate_version!())
        .about(ABOUT)
        .arg(
            Arg::with_name(OPT_CANONICALIZE)
                .short("f")
                .long(OPT_CANONICALIZE)
                .help(
                    "canonicalize by following every symlink in every component of the \
                     given name recursively; all but the last component must exist",
                ),
        )
        .arg(
            Arg::with_name(OPT_CANONICALIZE_EXISTING)
                .short("e")
                .long("canonicalize-existing")
                .help(
                    "canonicalize by following every symlink in every component of the \
                     given name recursively, all components must exist",
                ),
        )
        .arg(
            Arg::with_name(OPT_CANONICALIZE_MISSING)
                .short("m")
                .long(OPT_CANONICALIZE_MISSING)
                .help(
                    "canonicalize by following every symlink in every component of the \
                     given name recursively, without requirements on components existence",
                ),
        )
        .arg(
            Arg::with_name(OPT_NO_NEWLINE)
                .short("n")
                .long(OPT_NO_NEWLINE)
                .help("do not output the trailing delimiter"),
        )
        .arg(
            Arg::with_name(OPT_QUIET)
                .short("q")
                .long(OPT_QUIET)
                .help("suppress most error messages"),
        )
        .arg(
            Arg::with_name(OPT_SILENT)
                .short("s")
                .long(OPT_SILENT)
                .help("suppress most error messages"),
        )
        .arg(
            Arg::with_name(OPT_VERBOSE)
                .short("v")
                .long(OPT_VERBOSE)
                .help("report error message"),
        )
        .arg(
            Arg::with_name(OPT_ZERO)
                .short("z")
                .long(OPT_ZERO)
                .help("separate output with NUL rather than newline"),
        )
        .arg(Arg::with_name(ARG_FILES).multiple(true).takes_value(true))
}

fn show(path: &Path, no_newline: bool, use_zero: bool) {
    let path = path.to_str().unwrap();
    if use_zero {
        print!("{}\0", path);
    } else if no_newline {
        print!("{}", path);
    } else {
        println!("{}", path);
    }
    crash_if_err!(1, stdout().flush());
}
<commit_msg>readlink: eliminate duplicate code<commit_after>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Haitao Li <lihaitao@gmail.com>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

// spell-checker:ignore (ToDO) errno

#[macro_use]
extern crate uucore;

use clap::{crate_version, App, Arg};
use std::fs;
use std::io::{stdout, Write};
use std::path::{Path, PathBuf};
use uucore::display::Quotable;
use uucore::fs::{canonicalize, MissingHandling, ResolveMode};

const ABOUT: &str = "Print value of a symbolic link or canonical file name.";
const OPT_CANONICALIZE: &str = "canonicalize";
const OPT_CANONICALIZE_MISSING: &str = "canonicalize-missing";
const OPT_CANONICALIZE_EXISTING: &str = "canonicalize-existing";
const OPT_NO_NEWLINE: &str = "no-newline";
const OPT_QUIET: &str = "quiet";
const OPT_SILENT: &str = "silent";
const OPT_VERBOSE: &str = "verbose";
const OPT_ZERO: &str = "zero";

const ARG_FILES: &str = "files";

fn usage() -> String {
    format!("{0} [OPTION]... [FILE]...", uucore::execution_phrase())
}

pub fn uumain(args: impl uucore::Args) -> i32 {
    let usage = usage();
    let matches = uu_app().usage(&usage[..]).get_matches_from(args);

    let mut no_newline = matches.is_present(OPT_NO_NEWLINE);
    let use_zero = matches.is_present(OPT_ZERO);
    let silent = matches.is_present(OPT_SILENT) || matches.is_present(OPT_QUIET);
    let verbose = matches.is_present(OPT_VERBOSE);

    let res_mode = if matches.is_present(OPT_CANONICALIZE)
        || matches.is_present(OPT_CANONICALIZE_EXISTING)
        || matches.is_present(OPT_CANONICALIZE_MISSING)
    {
        ResolveMode::Logical
    } else {
        ResolveMode::None
    };

    let can_mode = if matches.is_present(OPT_CANONICALIZE_EXISTING) {
        MissingHandling::Existing
    } else if matches.is_present(OPT_CANONICALIZE_MISSING) {
        MissingHandling::Missing
    } else {
        MissingHandling::Normal
    };

    let files: Vec<String> = matches
        .values_of(ARG_FILES)
        .map(|v| v.map(ToString::to_string).collect())
        .unwrap_or_default();
    if files.is_empty() {
        crash!(
            1,
            "missing operand\nTry '{} --help' for more information",
            uucore::execution_phrase()
        );
    }

    if no_newline && files.len() > 1 && !silent {
        show_error!("ignoring --no-newline with multiple arguments");
        no_newline = false;
    }

    for f in &files {
        let p = PathBuf::from(f);
        let path_result = if res_mode == ResolveMode::None {
            fs::read_link(&p)
        } else {
            canonicalize(&p, can_mode, res_mode)
        };
        match path_result {
            Ok(path) => show(&path, no_newline, use_zero),
            Err(err) => {
                if verbose {
                    show_error!("{}: errno {}", f.maybe_quote(), err.raw_os_error().unwrap());
                }
                return 1;
            }
        }
    }

    0
}

pub fn uu_app() -> App<'static, 'static> {
    App::new(uucore::util_name())
        .version(crate_version!())
        .about(ABOUT)
        .arg(
            Arg::with_name(OPT_CANONICALIZE)
                .short("f")
                .long(OPT_CANONICALIZE)
                .help(
                    "canonicalize by following every symlink in every component of the \
                     given name recursively; all but the last component must exist",
                ),
        )
        .arg(
            Arg::with_name(OPT_CANONICALIZE_EXISTING)
                .short("e")
                .long("canonicalize-existing")
                .help(
                    "canonicalize by following every symlink in every component of the \
                     given name recursively, all components must exist",
                ),
        )
        .arg(
            Arg::with_name(OPT_CANONICALIZE_MISSING)
                .short("m")
                .long(OPT_CANONICALIZE_MISSING)
                .help(
                    "canonicalize by following every symlink in every component of the \
                     given name recursively, without requirements on components existence",
                ),
        )
        .arg(
            Arg::with_name(OPT_NO_NEWLINE)
                .short("n")
                .long(OPT_NO_NEWLINE)
                .help("do not output the trailing delimiter"),
        )
        .arg(
            Arg::with_name(OPT_QUIET)
                .short("q")
                .long(OPT_QUIET)
                .help("suppress most error messages"),
        )
        .arg(
            Arg::with_name(OPT_SILENT)
                .short("s")
                .long(OPT_SILENT)
                .help("suppress most error messages"),
        )
        .arg(
            Arg::with_name(OPT_VERBOSE)
                .short("v")
                .long(OPT_VERBOSE)
                .help("report error message"),
        )
        .arg(
            Arg::with_name(OPT_ZERO)
                .short("z")
                .long(OPT_ZERO)
                .help("separate output with NUL rather than newline"),
        )
        .arg(Arg::with_name(ARG_FILES).multiple(true).takes_value(true))
}

fn show(path: &Path, no_newline: bool, use_zero: bool) {
    let path = path.to_str().unwrap();
    if use_zero {
        print!("{}\0", path);
    } else if no_newline {
        print!("{}", path);
    } else {
        println!("{}", path);
    }
    crash_if_err!(1, stdout().flush());
}
<|endoftext|>


<commit_before>extern crate conv;
extern crate rand;

use self::conv::prelude::*;
use neat::gene::Gene as Gene;
use neat::mutation::Mutation as Mutation;

#[derive(Debug, Clone)]
pub struct Genome{
    genes: Vec<Gene>
}

const COMPATIBILITY_THRESHOLD: f64 = 1f64;
const MUTATE_ADD_NEURON_PROBABILITY: f64 = 0.33f64;
const MUTATE_CONNECTION_WEIGHT: f64 = 0.33f64;
const MUTATE_ADD_CONNECTION: f64 = 0.33f64;

impl Genome{

    pub fn new() -> Genome {
        Genome {
            genes: vec![]
        }
    }

    pub fn create_gene(&mut self, in_neuron_id: u32, out_neuron_id: u32, weight: f64) {
        let gene = Gene {
            in_neuron_id: in_neuron_id,
            out_neuron_id: out_neuron_id,
            weight: weight,
            ..Default::default()
        };
        self.genes.push(gene);
    }

    pub fn mutate(&mut self) {
        let random = rand::random::<f64>();
        if random > MUTATE_ADD_CONNECTION + MUTATE_CONNECTION_WEIGHT && self.genes.len() > 0 {
            self.mutate_add_neuron();
        } else if random > MUTATE_ADD_CONNECTION && self.genes.len() > 0 {
            self.mutate_connection_weight();
        } else {
            self.mutate_add_connection();
        }
    }

    fn mutate_add_connection(&self) {
        unimplemented!();
    }

    fn mutate_connection_weight(&self) {
        unimplemented!();
    }

    fn mutate_add_neuron(&mut self) {
        let (gene1, gene2) = {
            let mut rng = rand::thread_rng();
            let selected_gene = rand::sample(&mut rng, 0..self.genes.len(), 1)[0];
            let genes_len = self.genes.len().value_as::<u32>().unwrap();
            let gene = &mut self.genes[selected_gene];
            Mutation::add_neuron(gene, genes_len + 1)
        };
        self.genes.push(gene1);
        self.genes.push(gene2);
    }

    fn change_connection_weight(&mut self, gene: &mut Gene){
        Mutation::connection_weight(gene)
    }

    fn add_connection(&mut self, in_neuron_id: u32, out_neuron_id: u32) {
        let gene = Mutation::add_connection(in_neuron_id, out_neuron_id);
        self.genes.push(gene);
    }

    pub fn is_same_specie(&self, other: &Genome) -> bool{
        self.compatibility_distance(other) < COMPATIBILITY_THRESHOLD
    }

    pub fn total_weights(&self) -> f64{
        let mut total = 0f64;
        for gene in &self.genes {
            total += gene.weight;
        }
        total
    }

    pub fn total_genes(&self) -> usize{
        self.genes.len()
    }

    //http://nn.cs.utexas.edu/downloads/papers/stanley.ec02.pdf - Pag. 110
    //I have consider disjoint and excess genes as the same
    fn compatibility_distance(&self, other: &Genome) -> f64 {
        //TODO: optimize this method
        let c2 = 0.5f64;
        let c3 = 0.5f64;

        //Number of excess
        let n1 = self.genes.len().value_as::<f64>().unwrap();
        let n2 = other.genes.len().value_as::<f64>().unwrap();
        let n = n1.max(n2);

        if n == 0f64 {
            return 0f64; //no genes in any genome, the genomes are equal
        }

        let matching_genes  = self.genes.iter().filter(|i1_gene| other.genes.contains(i1_gene)).collect::<Vec<&Gene>>();

        let n3 = matching_genes.len().value_as::<f64>().unwrap();

        //Disjoint genes
        let d = n1 + n2 - (2f64 * n3);

        //average weight differences of matching genes
        let w1 = matching_genes.iter().fold(0f64, |acc, &m_gene| acc + (m_gene.weight + other.genes.get(other.genes.binary_search(m_gene).unwrap()).unwrap().weight)).abs();

        let w = w1 / n3;

        //compatibility distance
        let delta = (c2 * d / n) + c3 * w;
        delta
    }
}

#[cfg(test)]
mod tests {
    use neat::*;

    #[test]
    fn mutation_connection_weight(){
        let mut genome = Genome::new();
        genome.create_gene(1, 1, 1f64);
        let orig_gene = genome.genes[0].clone();
        genome.mutate_connection_weight();

        assert!(genome.genes[0].weight != orig_gene.weight);
    }

    #[test]
    fn mutation_add_connection(){
        let mut genome = Genome::new();
        genome.add_connection(1, 2);

        assert!(genome.genes[0].in_neuron_id == 1);
        assert!(genome.genes[0].out_neuron_id == 2);
    }

    #[test]
    fn mutation_add_neuron(){
        let mut genome = Genome::new();
        genome.create_gene(1, 2, 1f64);
        genome.mutate_add_neuron();

        assert!(!genome.genes[0].enabled);
        assert!(genome.genes[1].in_neuron_id == genome.genes[0].in_neuron_id);
        assert!(genome.genes[1].out_neuron_id == 2);
        assert!(genome.genes[2].in_neuron_id == 2);
        assert!(genome.genes[2].out_neuron_id == genome.genes[0].out_neuron_id);
    }
}
<commit_msg>Fix mutate connection genes<commit_after>extern crate conv;
extern crate rand;

use self::conv::prelude::*;
use neat::gene::Gene as Gene;
use neat::mutation::Mutation as Mutation;

#[derive(Debug, Clone)]
pub struct Genome{
    genes: Vec<Gene>
}

const COMPATIBILITY_THRESHOLD: f64 = 1f64;
const MUTATE_ADD_NEURON_PROBABILITY: f64 = 0.33f64;
const MUTATE_CONNECTION_WEIGHT: f64 = 0.33f64;
const MUTATE_ADD_CONNECTION: f64 = 0.33f64;

impl Genome{

    pub fn new() -> Genome {
        Genome {
            genes: vec![]
        }
    }

    pub fn create_gene(&mut self, in_neuron_id: u32, out_neuron_id: u32, weight: f64) {
        let gene = Gene {
            in_neuron_id: in_neuron_id,
            out_neuron_id: out_neuron_id,
            weight: weight,
            ..Default::default()
        };
        self.genes.push(gene);
    }

    pub fn mutate(&mut self) {
        let random = rand::random::<f64>();
        if random > MUTATE_ADD_CONNECTION + MUTATE_CONNECTION_WEIGHT && self.genes.len() > 0 {
            self.mutate_add_neuron();
        } else if random > MUTATE_ADD_CONNECTION && self.genes.len() > 0 {
            self.mutate_connection_weight();
        } else {
            self.mutate_add_connection();
        }
    }

    fn mutate_add_connection(&self) {
        unimplemented!();
    }

    fn mutate_connection_weight(&mut self) {
        let mut rng = rand::thread_rng();
        let selected_gene = rand::sample(&mut rng, 0..self.genes.len(), 1)[0];
        let gene = &mut self.genes[selected_gene];
        Mutation::connection_weight(gene);
    }

    fn mutate_add_neuron(&mut self) {
        let (gene1, gene2) = {
            let mut rng = rand::thread_rng();
            let selected_gene = rand::sample(&mut rng, 0..self.genes.len(), 1)[0];
            let genes_len = self.genes.len().value_as::<u32>().unwrap();
            let gene = &mut self.genes[selected_gene];
            Mutation::add_neuron(gene, genes_len + 1)
        };
        self.genes.push(gene1);
        self.genes.push(gene2);
    }

    fn change_connection_weight(&mut self, gene: &mut Gene){
        Mutation::connection_weight(gene)
    }

    fn add_connection(&mut self, in_neuron_id: u32, out_neuron_id: u32) {
        let gene = Mutation::add_connection(in_neuron_id, out_neuron_id);
        self.genes.push(gene);
    }

    pub fn is_same_specie(&self, other: &Genome) -> bool{
        self.compatibility_distance(other) < COMPATIBILITY_THRESHOLD
    }

    pub fn total_weights(&self) -> f64{
        let mut total = 0f64;
        for gene in &self.genes {
            total += gene.weight;
        }
        total
    }

    pub fn total_genes(&self) -> usize{
        self.genes.len()
    }

    //http://nn.cs.utexas.edu/downloads/papers/stanley.ec02.pdf - Pag. 110
    //I have consider disjoint and excess genes as the same
    fn compatibility_distance(&self, other: &Genome) -> f64 {
        //TODO: optimize this method
        let c2 = 0.5f64;
        let c3 = 0.5f64;

        //Number of excess
        let n1 = self.genes.len().value_as::<f64>().unwrap();
        let n2 = other.genes.len().value_as::<f64>().unwrap();
        let n = n1.max(n2);

        if n == 0f64 {
            return 0f64; //no genes in any genome, the genomes are equal
        }

        let matching_genes  = self.genes.iter().filter(|i1_gene| other.genes.contains(i1_gene)).collect::<Vec<&Gene>>();

        let n3 = matching_genes.len().value_as::<f64>().unwrap();

        //Disjoint genes
        let d = n1 + n2 - (2f64 * n3);

        //average weight differences of matching genes
        let w1 = matching_genes.iter().fold(0f64, |acc, &m_gene| acc + (m_gene.weight + other.genes.get(other.genes.binary_search(m_gene).unwrap()).unwrap().weight)).abs();

        let w = w1 / n3;

        //compatibility distance
        let delta = (c2 * d / n) + c3 * w;
        delta
    }
}

#[cfg(test)]
mod tests {
    use neat::*;

    #[test]
    fn mutation_connection_weight(){
        let mut genome = Genome::new();
        genome.create_gene(1, 1, 1f64);
        let orig_gene = genome.genes[0].clone();
        genome.mutate_connection_weight();

        assert!(genome.genes[0].weight != orig_gene.weight);
    }

    #[test]
    fn mutation_add_connection(){
        let mut genome = Genome::new();
        genome.add_connection(1, 2);

        assert!(genome.genes[0].in_neuron_id == 1);
        assert!(genome.genes[0].out_neuron_id == 2);
    }

    #[test]
    fn mutation_add_neuron(){
        let mut genome = Genome::new();
        genome.create_gene(1, 2, 1f64);
        genome.mutate_add_neuron();

        assert!(!genome.genes[0].enabled);
        assert!(genome.genes[1].in_neuron_id == genome.genes[0].in_neuron_id);
        assert!(genome.genes[1].out_neuron_id == 2);
        assert!(genome.genes[2].in_neuron_id == 2);
        assert!(genome.genes[2].out_neuron_id == genome.genes[0].out_neuron_id);
    }
}
<|endoftext|>


<commit_before>use node::{ Expr };
use parser::{ Parse, Context };
use { Token, TokenValue };
use operator::{ OperatorOptions, OperatorKind, Associativity };
use error::{ Error, ErrorMessage };
use { Result, Expect };

impl<'c> Parse<'c> for Expr<'c> {
    type Output = Expr<'c>;

    fn parse<'r, I>(parser: &mut Context<'r, I>)
        -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
    {
        parse_expression(parser, 0)
    }
}

fn parse_expression<'p, 'c, I>(parser: &mut Context<'p, I>, min_precedence: u16)
    -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
{
    println!("parse_expression");

    let mut expr = try!(get_primary(parser));
    let mut token = try!(parser.current());

    loop {
        if let TokenValue::Operator(op_str) = token.value {
            if let OperatorOptions { kind: OperatorKind::Binary(associativity), precedence, .. } = *parser.get_operator_options(op_str) {
                if precedence >= min_precedence {
                    try!(parser.next());

                    // if callable ...
                        // TODO: Callable.
                    // else
                    let expr1 = try!(parse_expression(parser, match associativity {
                        Associativity::Left => precedence + 1,
                        Associativity::Right => precedence,
                    }));
                    expr = Expr::BinaryOperator {
                        value: op_str,
                        left: Box::new(expr.clone()),
                        right: Box::new(expr1),
                        line: token.line
                    };
                    // endif

                    token = try!(parser.current());

                    continue;
                }
            }
        }
        break;
    }

    if 0 == min_precedence {
        return parse_conditional_expression(parser, expr);
    }

    Ok(expr)
}

/// Parses expression and returns handle to one that should be executed first.
fn get_primary<'p, 'c, I>(parser: &mut Context<'p, I>)
    -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
{
    let token = try!(parser.current());

    if let TokenValue::Operator(op_str) = token.value {
        if let OperatorOptions { kind: OperatorKind::Unary, precedence, .. } = *parser.get_operator_options(op_str) {
            try!(parser.next());
            let expr = try!(parse_expression(parser, precedence));
            let parsed_expr = Expr::UnaryOperator {
                value: op_str,
                expr: Box::new(expr),
                line: token.line
            };
            return parse_postfix_expression(parser, parsed_expr);
        }
    }

    if let TokenValue::Punctuation('(') = token.value {
        try!(parser.next());
        let parsed_expr = try!(parse_expression(parser, 0));
        if let Err(_) = parser.tokens.expect(TokenValue::Punctuation(')')) {
            return Err(Error::new_at(ErrorMessage::ParenthesisNotClosed, token.line));
        }
        return parse_postfix_expression(parser, parsed_expr);
    }

    parse_primary_expression(parser)
}

/// Parses expression and returns handle to one that should be executed first.
fn parse_primary_expression<'p, 'c, I>(parser: &mut Context<'p, I>)
    -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
{
    println!("parse_primary_expression");
    let token = try!(parser.current());

    match token.value {
        TokenValue::Name(_) => unreachable!("TokenValue::Name"),
        TokenValue::Value(_) => unreachable!("TokenValue::Value"),
        TokenValue::InterpolationStart => unreachable!("TokenValue::InterpolationStart"),
        TokenValue::Operator(_) => unreachable!("TokenValue::Operator"),
        TokenValue::Punctuation('[') => unreachable!("TokenValue::Punctuation('[')"),
        TokenValue::Punctuation('{') => unreachable!("TokenValue::Punctuation('{')"),
        other => return Err(Error::new_at(
            ErrorMessage::UnexpectedToken(other.into()),
            token.line
        )),
    }
    unimplemented!()
}

/// Parses expression and returns handle to one that should be executed first.
fn parse_postfix_expression<'p, 'c, I>(parser: &mut Context<'p, I>, expr: Expr<'c>)
    -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
{
    println!("parse_postfix_expression");
    unimplemented!()
}

fn parse_conditional_expression<'p, 'c, I>(parser: &mut Context<'p, I>, expr: Expr<'c>)
    -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
{
    println!("parse_conditional_expression");
    unimplemented!()
}
<commit_msg>Begin string expression parser.<commit_after>use node::{ Expr };
use parser::{ Parse, Context };
use { Token, TokenValue };
use operator::{ OperatorOptions, OperatorKind, Associativity };
use error::{ Error, ErrorMessage };
use { Result, Expect };
use value::{ TwigValueRef, TwigNumberRef };

impl<'c> Parse<'c> for Expr<'c> {
    type Output = Expr<'c>;

    fn parse<'r, I>(parser: &mut Context<'r, I>)
        -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
    {
        parse_expression(parser, 0)
    }
}

fn parse_expression<'p, 'c, I>(parser: &mut Context<'p, I>, min_precedence: u16)
    -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
{
    println!("parse_expression");

    let mut expr = try!(get_primary(parser));
    let mut token = try!(parser.current());

    loop {
        if let TokenValue::Operator(op_str) = token.value {
            if let OperatorOptions { kind: OperatorKind::Binary(associativity), precedence, .. } = *parser.get_operator_options(op_str) {
                if precedence >= min_precedence {
                    try!(parser.next());

                    // if callable ...
                        // TODO: Callable.
                    // else
                    let expr1 = try!(parse_expression(parser, match associativity {
                        Associativity::Left => precedence + 1,
                        Associativity::Right => precedence,
                    }));
                    expr = Expr::BinaryOperator {
                        value: op_str,
                        left: Box::new(expr.clone()),
                        right: Box::new(expr1),
                        line: token.line
                    };
                    // endif

                    token = try!(parser.current());

                    continue;
                }
            }
        }
        break;
    }

    if 0 == min_precedence {
        return parse_conditional_expression(parser, expr);
    }

    Ok(expr)
}

/// Parses expression and returns handle to one that should be executed first.
fn get_primary<'p, 'c, I>(parser: &mut Context<'p, I>)
    -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
{
    let token = try!(parser.current());

    if let TokenValue::Operator(op_str) = token.value {
        if let OperatorOptions { kind: OperatorKind::Unary, precedence, .. } = *parser.get_operator_options(op_str) {
            try!(parser.next());
            let expr = try!(parse_expression(parser, precedence));
            let parsed_expr = Expr::UnaryOperator {
                value: op_str,
                expr: Box::new(expr),
                line: token.line
            };
            return parse_postfix_expression(parser, parsed_expr);
        }
    }

    if let TokenValue::Punctuation('(') = token.value {
        try!(parser.next());
        let parsed_expr = try!(parse_expression(parser, 0));
        if let Err(_) = parser.tokens.expect(TokenValue::Punctuation(')')) {
            return Err(Error::new_at(ErrorMessage::ParenthesisNotClosed, token.line));
        }
        return parse_postfix_expression(parser, parsed_expr);
    }

    parse_primary_expression(parser)
}

/// Parses expression and returns handle to one that should be executed first.
fn parse_primary_expression<'p, 'c, I>(parser: &mut Context<'p, I>)
    -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
{
    println!("parse_primary_expression");
    let token = try!(parser.current());

    let expr = match token.value {
        TokenValue::Name(_) => unreachable!("TokenValue::Name"),
        TokenValue::Value(ref value) => match *value {
            TwigValueRef::Num(_) => unreachable!("TwigValueRef::Num"),
            TwigValueRef::Str(_) => try!(parse_string_expression(parser)),
        },
        TokenValue::InterpolationStart => try!(parse_string_expression(parser)),
        TokenValue::Operator(_) => unreachable!("TokenValue::Operator"),
        TokenValue::Punctuation('[') => unreachable!("TokenValue::Punctuation('[')"),
        TokenValue::Punctuation('{') => unreachable!("TokenValue::Punctuation('{')"),
        other => return Err(Error::new_at(
            ErrorMessage::UnexpectedToken(other.into()),
            token.line
        )),
    };

    parse_postfix_expression(parser, expr)
}

/// Parses expression and returns handle to one that should be executed first.
fn parse_string_expression<'p, 'c, I>(parser: &mut Context<'p, I>)
    -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
{
    println!("parse_string_expression");
    unimplemented!()
}

/// Parses expression and returns handle to one that should be executed first.
fn parse_postfix_expression<'p, 'c, I>(parser: &mut Context<'p, I>, expr: Expr<'c>)
    -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
{
    println!("parse_postfix_expression");
    unimplemented!()
}

fn parse_conditional_expression<'p, 'c, I>(parser: &mut Context<'p, I>, expr: Expr<'c>)
    -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
{
    println!("parse_conditional_expression");
    unimplemented!()
}
<|endoftext|>


<commit_before>//! Set up resource content for game.

use std::collections::HashMap;
use std::iter::FromIterator;
use glium;
use image::{self, GenericImage};
use euclid::Point2D;
use vitral_atlas;
use vitral;
use calx_color::color::*;
use calx_resource::ResourceStore;
use world::BrushBuilder;
use backend::{Backend, Font};

impl_store!(FONT, String, Font);

fn to_image_buffer<I>(image: &I) -> vitral::ImageBuffer
    where I: image::GenericImage<Pixel = image::Rgba<u8>>
{
    vitral::ImageBuffer::from_iter(image.width(),
                                   image.height(),
                                   &mut image.pixels().map(|p| unsafe {
                                       ::std::mem::transmute::<image::Rgba<u8>, u32>(p.2)
                                   }))
}

pub fn font(display: &glium::Display, backend: &mut Backend) {
    use tilesheet::tilesheet_bounds;

    const PATH: &'static str = "display/assets/font.png";

    let mut font_sheet = image::open(PATH).expect(&format!("Font sheet '{}' not found", PATH));

    // Use the tilesheet machinery to extract individual glyph boundaries from the special font
    // tilesheet.
    let bounds = tilesheet_bounds(&font_sheet);

    // Construct Vitral ImageBuffers of the glyphs.
    let glyphs: Vec<vitral::ImageBuffer> = bounds.iter()
                                                 .map(|rect| {
                                                     to_image_buffer(&font_sheet.sub_image(
                rect.origin.x as u32, rect.origin.y as u32,
                rect.size.width as u32, rect.size.height as u32))
                                                 })
                                                 .collect();

    assert!(glyphs.len() == 96, "Unexpected number of font glyphs");
    let font_height = glyphs[0].size.height;

    // Build the font atlas and map the items to CharData.
    let items: Vec<vitral::CharData<usize>> = vitral_atlas::build(&glyphs, 2048, |img| {
                                                  backend.make_texture(display, img)
                                              })
                                                  .expect("Atlas construction failed")
                                                  .into_iter()
                                                  .map(|image| {
                                                      let advance = image.size.width as f32;
                                                      vitral::CharData {
                                                          image: image,
                                                          draw_offset:
                                                              Point2D::new(0.0, font_height as f32),
                                                          advance: advance,
                                                      }
                                                  })
                                                  .collect();

    let font = Font(vitral::FontData {
        chars: HashMap::from_iter((32u8..128).map(|c| c as char).zip(items.into_iter())),
        height: font_height as f32,
    });

    Font::insert_resource("default".to_string(), font);
}

/// Init the static brush assets.
pub fn brushes(display: &glium::Display, backend: &mut Backend) {
    // FIXME: This API needs to be more ergonomic. In particular, need better syntactic cues for
    // brush boundries.

    BrushBuilder::new()
        .file("display/assets/floors.png")
        ////
        .tile(0, 0)
        .brush("blank_floor")
        ////
        .color(DARKGREEN)
        .tile(32, 0)
        .brush("grass")
        ////
        .color(DARKGREEN)
        .tile(64, 0)
        .brush("grass2")
        ////
        .color(SLATEGRAY)
        .tile(32, 0)
        .brush("ground")
        ////
        .color(SLATEGRAY)
        .tile(32, 0)
        .brush("corridor")
        ////
        .color(ROYALBLUE)
        .tile(96, 0)
        .brush("water")
        ////
        .file("display/assets/portals.png")
        ////
        .color(LIGHTCYAN)
        .tile(0, 0)
        .frame()
        .tile(32, 0)
        .frame()
        .tile(64, 0)
        .frame()
        .tile(96, 0)
        .frame()
        .tile(128, 0)
        .frame()
        .tile(160, 0)
        .frame()
        .tile(192, 0)
        .frame()
        .tile(224, 0)
        .frame()
        .tile(256, 0)
        .frame()
        .tile(288, 0)
        .frame()
        .tile(320, 0)
        .frame()
        .tile(352, 0)
        .frame()
        .tile(384, 0)
        .brush("gate")
        ////
        .file("display/assets/props.png")
        ////
        .color(RED)
        .tile(0, 0)
        .brush("cursor")
        .color(RED)
        .tile(32, 0)
        .brush("cursor_top")
        .color(ORANGE)
        .tile(0, 0)
        .brush("portal") // TODO: This thing is a temporary display helper for mapedit, maybe remove when can?
        ////
        .color(SADDLEBROWN)
        .tile(160, 64)
        .color(GREEN)
        .tile(192, 64)
        .brush("tree")
        ////
        .file("display/assets/walls.png")
        ////
        .color(LIGHTSLATEGRAY)
        .wall(0, 0, 32, 0)
        .brush("wall")

        .color(LIGHTSLATEGRAY)
        .wall(0, 0, 96, 0)
        .brush("open_door")

        // XXX: Wall helper function doesn't handle complex splats.
        //
        .color(SADDLEBROWN)
        .splat(128, 0, 16, 32).offset(16, 16)
        .color(LIGHTSLATEGRAY)
        .splat(0, 0, 16, 32).offset(16, 16)

        .frame()
        .color(SADDLEBROWN)
        .splat(128 + 16, 0, 16, 32).offset(0, 16)
        .color(LIGHTSLATEGRAY)
        .splat(16, 0, 16, 32).offset(0, 16)

        .frame()
        .color(SADDLEBROWN)
        .splat(160, 0, 16, 32).offset(16, 16)
        .color(LIGHTSLATEGRAY)
        .splat(96, 0, 16, 32).offset(16, 16)

        .frame()
        .color(SADDLEBROWN)
        .splat(160 + 16, 0, 16, 32).offset(0, 16)
        .color(LIGHTSLATEGRAY)
        .splat(96 + 16, 0, 16, 32).offset(0, 16)

        .brush("door")
        // Door finally ends here.

        ////
        .file("display/assets/blobs.png")
        ////
        .color(BLACK)
        .blob(0, 64, 0, 96, 0, 128)
        .brush("solid-blob")
        .color(DARKGOLDENROD)
        .blob(0, 0, 0, 32, 0, 160)
        .brush("rock")
        ////
        .file("display/assets/mobs.png")
        .color(AZURE)
        .tile(0, 0)
        .bob()
        .brush("player")
        .color(GREEN)
        .tile(32, 0)
        .bob()
        .brush("snake")
        .color(OLIVE)
        .tile(64, 0)
        .bob()
        .brush("dreg")
        ////
        .finish(|img| backend.make_texture(&display, img));
}
<commit_msg>Transparent portal visualization<commit_after>//! Set up resource content for game.

use std::str::FromStr;
use std::collections::HashMap;
use std::iter::FromIterator;
use glium;
use image::{self, GenericImage};
use euclid::Point2D;
use vitral_atlas;
use vitral;
use calx_color::Rgba;
use calx_color::color::*;
use calx_resource::ResourceStore;
use world::BrushBuilder;
use backend::{Backend, Font};

impl_store!(FONT, String, Font);

fn to_image_buffer<I>(image: &I) -> vitral::ImageBuffer
    where I: image::GenericImage<Pixel = image::Rgba<u8>>
{
    vitral::ImageBuffer::from_iter(image.width(),
                                   image.height(),
                                   &mut image.pixels().map(|p| unsafe {
                                       ::std::mem::transmute::<image::Rgba<u8>, u32>(p.2)
                                   }))
}

pub fn font(display: &glium::Display, backend: &mut Backend) {
    use tilesheet::tilesheet_bounds;

    const PATH: &'static str = "display/assets/font.png";

    let mut font_sheet = image::open(PATH).expect(&format!("Font sheet '{}' not found", PATH));

    // Use the tilesheet machinery to extract individual glyph boundaries from the special font
    // tilesheet.
    let bounds = tilesheet_bounds(&font_sheet);

    // Construct Vitral ImageBuffers of the glyphs.
    let glyphs: Vec<vitral::ImageBuffer> = bounds.iter()
                                                 .map(|rect| {
                                                     to_image_buffer(&font_sheet.sub_image(
                rect.origin.x as u32, rect.origin.y as u32,
                rect.size.width as u32, rect.size.height as u32))
                                                 })
                                                 .collect();

    assert!(glyphs.len() == 96, "Unexpected number of font glyphs");
    let font_height = glyphs[0].size.height;

    // Build the font atlas and map the items to CharData.
    let items: Vec<vitral::CharData<usize>> = vitral_atlas::build(&glyphs, 2048, |img| {
                                                  backend.make_texture(display, img)
                                              })
                                                  .expect("Atlas construction failed")
                                                  .into_iter()
                                                  .map(|image| {
                                                      let advance = image.size.width as f32;
                                                      vitral::CharData {
                                                          image: image,
                                                          draw_offset:
                                                              Point2D::new(0.0, font_height as f32),
                                                          advance: advance,
                                                      }
                                                  })
                                                  .collect();

    let font = Font(vitral::FontData {
        chars: HashMap::from_iter((32u8..128).map(|c| c as char).zip(items.into_iter())),
        height: font_height as f32,
    });

    Font::insert_resource("default".to_string(), font);
}

/// Init the static brush assets.
pub fn brushes(display: &glium::Display, backend: &mut Backend) {
    // FIXME: This API needs to be more ergonomic. In particular, need better syntactic cues for
    // brush boundries.

    BrushBuilder::new()
        .file("display/assets/floors.png")
        ////
        .tile(0, 0)
        .brush("blank_floor")
        ////
        .color(DARKGREEN)
        .tile(32, 0)
        .brush("grass")
        ////
        .color(DARKGREEN)
        .tile(64, 0)
        .brush("grass2")
        ////
        .color(SLATEGRAY)
        .tile(32, 0)
        .brush("ground")
        ////
        .color(SLATEGRAY)
        .tile(32, 0)
        .brush("corridor")
        ////
        .color(ROYALBLUE)
        .tile(96, 0)
        .brush("water")
        ////
        .file("display/assets/portals.png")
        ////
        .color(LIGHTCYAN)
        .tile(0, 0)
        .frame()
        .tile(32, 0)
        .frame()
        .tile(64, 0)
        .frame()
        .tile(96, 0)
        .frame()
        .tile(128, 0)
        .frame()
        .tile(160, 0)
        .frame()
        .tile(192, 0)
        .frame()
        .tile(224, 0)
        .frame()
        .tile(256, 0)
        .frame()
        .tile(288, 0)
        .frame()
        .tile(320, 0)
        .frame()
        .tile(352, 0)
        .frame()
        .tile(384, 0)
        .brush("gate")
        ////
        .file("display/assets/props.png")
        ////
        .color(RED)
        .tile(0, 0)
        .brush("cursor")
        .color(RED)
        .tile(32, 0)
        .brush("cursor_top")
        .color(Rgba::from_str("#fa08").unwrap())
        .tile(0, 0)
        .brush("portal") // TODO: This thing is a temporary display helper for mapedit, maybe remove when can?
        ////
        .color(SADDLEBROWN)
        .tile(160, 64)
        .color(GREEN)
        .tile(192, 64)
        .brush("tree")
        ////
        .file("display/assets/walls.png")
        ////
        .color(LIGHTSLATEGRAY)
        .wall(0, 0, 32, 0)
        .brush("wall")

        .color(LIGHTSLATEGRAY)
        .wall(0, 0, 96, 0)
        .brush("open_door")

        // XXX: Wall helper function doesn't handle complex splats.
        //
        .color(SADDLEBROWN)
        .splat(128, 0, 16, 32).offset(16, 16)
        .color(LIGHTSLATEGRAY)
        .splat(0, 0, 16, 32).offset(16, 16)

        .frame()
        .color(SADDLEBROWN)
        .splat(128 + 16, 0, 16, 32).offset(0, 16)
        .color(LIGHTSLATEGRAY)
        .splat(16, 0, 16, 32).offset(0, 16)

        .frame()
        .color(SADDLEBROWN)
        .splat(160, 0, 16, 32).offset(16, 16)
        .color(LIGHTSLATEGRAY)
        .splat(96, 0, 16, 32).offset(16, 16)

        .frame()
        .color(SADDLEBROWN)
        .splat(160 + 16, 0, 16, 32).offset(0, 16)
        .color(LIGHTSLATEGRAY)
        .splat(96 + 16, 0, 16, 32).offset(0, 16)

        .brush("door")
        // Door finally ends here.

        ////
        .file("display/assets/blobs.png")
        ////
        .color(BLACK)
        .blob(0, 64, 0, 96, 0, 128)
        .brush("solid-blob")
        .color(DARKGOLDENROD)
        .blob(0, 0, 0, 32, 0, 160)
        .brush("rock")
        ////
        .file("display/assets/mobs.png")
        .color(AZURE)
        .tile(0, 0)
        .bob()
        .brush("player")
        .color(GREEN)
        .tile(32, 0)
        .bob()
        .brush("snake")
        .color(OLIVE)
        .tile(64, 0)
        .bob()
        .brush("dreg")
        ////
        .finish(|img| backend.make_texture(&display, img));
}
<|endoftext|>


<commit_before>// Check that `async fn` inside of an impl with `'_`
// in the header compiles correctly.
//
// Regression test for #63500.
//
// check-pass

#![feature(async_await)]

struct Foo<'a>(&'a u8);

impl Foo<'_> {
    async fn bar() {}
}

fn main() { }
<commit_msg>add edition to regression test<commit_after>// Check that `async fn` inside of an impl with `'_`
// in the header compiles correctly.
//
// Regression test for #63500.
//
// check-pass
// edition:2018

#![feature(async_await)]

struct Foo<'a>(&'a u8);

impl Foo<'_> {
    async fn bar() {}
}

fn main() { }
<|endoftext|>