<commit_before>#![crate_name = "docopt_macros"]
#![crate_type = "dylib"]
#![feature(plugin_registrar, macro_rules, quote)]

extern crate syntax;
extern crate rustc;
extern crate docopt;

use std::collections::HashMap;

use rustc::plugin::Registry;
use syntax::ast;
use syntax::codemap;
use syntax::ext::base::{ExtCtxt, MacResult, MacItems, DummyResult};
use syntax::ext::build::AstBuilder;
use syntax::fold::Folder;
use syntax::parse::common::SeqSep;
use syntax::parse::parser::Parser;
use syntax::parse::token;
use syntax::print::pprust;
use syntax::ptr::P;

use docopt::{DEFAULT_CONFIG, Docopt, ValueMap};
use docopt::parse::{Options, Atom, Positional, Zero, One};

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("docopt", expand);
}

fn expand(cx: &mut ExtCtxt, span: codemap::Span, tts: &[ast::TokenTree])
         -> Box<MacResult+'static> {
    let parsed = match MacParser::new(cx, tts).parse() {
        Ok(parsed) => parsed,
        Err(_) => return DummyResult::any(span),
    };
    parsed.items(cx)
}

/// Parsed corresponds to the result of parsing a `docopt` macro call.
/// It can be used to write a corresponding struct.
struct Parsed {
    struct_info: StructInfo,
    doc: Docopt,
    /// Overrided type annotations for struct members. May be empty.
    /// When a type annotation for an atom doesn't exist, then one is
    /// inferred automatically. It is one of: `bool`, `uint`, `String` or
    /// `Vec<String>`.
    types: HashMap<Atom, P<ast::Ty>>,
}

impl Parsed {
    /// Returns a macro result suitable for expansion.
    /// Contains two items: one for the struct and one for the struct impls.
    fn items(&self, cx: &ExtCtxt) -> Box<MacResult+'static> {
        let mut its = vec!();
        its.push(self.struct_decl(cx));

        let struct_name = self.struct_info.name;
        let full_doc = self.doc.parser().full_doc.as_slice();
        its.push(quote_item!(cx,
            impl docopt::FlagParser for $struct_name {
                #[allow(dead_code)]
                fn parse_args(conf: docopt::Config, args: &[&str])
                             -> Result<$struct_name, docopt::Error> {
                    docopt::docopt_args(conf, args, $full_doc).and_then(|v| {
                        v.decode()
                    })
                }
            }
        ).unwrap());
        MacItems::new(its.into_iter())
    }

    /// Returns an item for the struct definition.
    fn struct_decl(&self, cx: &ExtCtxt) -> P<ast::Item> {
        let name = self.struct_info.name.clone();
        let vis = if self.struct_info.public { ast::Public }
                  else { ast::Inherited };
        let def = ast::StructDef {
            fields: self.struct_fields(cx),
            ctor_id: None
        };

        let sp = codemap::DUMMY_SP;
        let mut traits = vec![meta_item(cx, "Decodable")];
        for trait_name in self.struct_info.deriving.iter() {
            traits.push(meta_item(cx, trait_name.as_slice()));
        }
        let deriving = cx.meta_list(sp, intern("deriving"), traits);
        let attrs = vec![cx.attribute(codemap::DUMMY_SP, deriving)];
        let st = cx.item_struct(sp, name.clone(), def);
        cx.item(sp, name, attrs, st.node.clone()).map(|mut it| {
            it.vis = vis;
            it
        })
    }

    /// Returns a list of fields for the struct definition.
    /// Handles type annotations.
    fn struct_fields(&self, cx: &ExtCtxt) -> Vec<ast::StructField> {
        let mut fields: Vec<ast::StructField> = vec!();
        for (atom, opts) in self.doc.parser().descs.iter() {
            let name = ValueMap::key_to_struct_field(atom.to_string().as_slice());
            let ty = match self.types.find(atom) {
                None => self.pat_type(cx, atom, opts),
                Some(ty) => ty.clone(),
            };
            fields.push(self.mk_struct_field(name.as_slice(), ty));
        }
        fields
    }

    /// Returns an inferred type for a usage pattern.
    /// This is only invoked when a type annotation is not present.
    fn pat_type(&self, cx: &ExtCtxt, atom: &Atom, opts: &Options) -> P<ast::Ty> {
        match (opts.repeats, &opts.arg) {
            (false, &Zero) => {
                match atom {
                    &Positional(_) => quote_ty!(cx, String),
                    _ => quote_ty!(cx, bool),
                }
            }
            (true, &Zero) => {
                match atom {
                    &Positional(_) => quote_ty!(cx, Vec<String>),
                    _ => quote_ty!(cx, uint),
                }
            }
            (false, &One(_)) => quote_ty!(cx, String),
            (true, &One(_)) => quote_ty!(cx, Vec<String>),
        }
    }

    /// Creates a struct field from a member name and type.
    fn mk_struct_field(&self, name: &str, ty: P<ast::Ty>) -> ast::StructField {
        codemap::dummy_spanned(ast::StructField_ {
            kind: ast::NamedField(ident(name), ast::Public),
            id: ast::DUMMY_NODE_ID,
            ty: ty,
            attrs: vec!(),
        })
    }
}

/// State for parsing a `docopt` macro invocation.
struct MacParser<'a, 'b:'a> {
    cx: &'a mut ExtCtxt<'b>,
    p: Parser<'b>,
}

impl<'a, 'b> MacParser<'a, 'b> {
    fn new(cx: &'a mut ExtCtxt<'b>, tts: &[ast::TokenTree]) -> MacParser<'a, 'b> {
        let p = cx.new_parser_from_tts(tts);
        MacParser { cx: cx, p: p }
    }

    /// Main entry point for parsing arguments to `docopt` macro.
    /// First looks for an identifier for the struct name.
    /// Second, a string containing the docopt usage patterns.
    /// Third, an optional list of type annotations.
    fn parse(&mut self) -> Result<Parsed, ()> {
        if self.p.token == token::EOF {
            self.cx.span_err(self.cx.call_site(), "macro expects arguments");
            return Err(());
        }
        let struct_info = try!(self.parse_struct_info());
        let docstr = try!(self.parse_str());

        let sep = SeqSep {
            sep: Some(token::COMMA),
            trailing_sep_allowed: true,
        };
        let types = self.p.parse_seq_to_end(
            &token::EOF, sep, |p| MacParser::parse_type_annotation(p)
        ).into_iter()
         .map(|(ident, ty)| {
             let field_name = token::get_ident(ident).to_string();
             let key = ValueMap::struct_field_to_key(field_name.as_slice());
             (Atom::new(key.as_slice()), ty)
          })
         .collect::<HashMap<Atom, P<ast::Ty>>>();
        self.p.expect(&token::EOF);

        // This config does not matter because we're only asking for the
        // usage patterns in the Docopt string. The configuration does not
        // affect the retrieval of usage patterns.
        let doc = match Docopt::new(DEFAULT_CONFIG.clone(), docstr.as_slice()) {
            Ok(doc) => doc,
            Err(err) => {
                self.cx.span_err(self.cx.call_site(),
                                 format!("Invalid Docopt usage: {}",
                                         err).as_slice());
                return Err(());
            }
        };
        Ok(Parsed {
            struct_info: struct_info,
            doc: doc,
            types: types,
        })
    }

    /// Parses a single string literal. On failure, an error is logged and
    /// unit is returned.
    fn parse_str(&mut self) -> Result<String, ()> {
        fn lit_is_str(lit: &ast::Lit) -> bool {
            match lit.node {
                ast::LitStr(_, _) => true,
                _ => false,
            }
        }
        fn lit_to_string(lit: &ast::Lit) -> String {
            match lit.node {
                ast::LitStr(ref s, _) => s.to_string(),
                _ => panic!("BUG: expected string literal"),
            }
        }
        let exp = self.cx.expander().fold_expr(self.p.parse_expr());
        let s = match exp.node {
            ast::ExprLit(ref lit) if lit_is_str(&**lit) => {
                lit_to_string(&**lit)
            }
            _ => {
                let err = format!("Expected string literal but got {}",
                                  pprust::expr_to_string(&*exp));
                self.cx.span_err(exp.span, err.as_slice());
                return Err(());
            }
        };
        self.p.bump();
        Ok(s)
    }

    /// Parses a type annotation in a `docopt` invocation of the form
    /// `ident: Ty`.
    /// Note that this is a static method as it is used as a HOF.
    fn parse_type_annotation(p: &mut Parser) -> (ast::Ident, P<ast::Ty>) {
        let ident = p.parse_ident();
        p.expect(&token::COLON);
        let ty = p.parse_ty(false);
        (ident, ty)
    }

    /// Parses struct information, like visibility, name and deriving.
    fn parse_struct_info(&mut self) -> Result<StructInfo, ()> {
        let public = self.p.eat_keyword(token::keywords::Pub);
        let mut info = StructInfo {
            name: self.p.parse_ident(),
            public: public,
            deriving: vec![],
        };
        if self.p.eat(&token::COMMA) { return Ok(info); }
        let deriving = self.p.parse_ident();
        if deriving.as_str() != "deriving" {
            let err = format!("Expected 'deriving' keyword but got '{}'",
                              deriving);
            self.cx.span_err(self.cx.call_site(), err.as_slice());
            return Err(());
        }
        while !self.p.eat(&token::COMMA) {
            info.deriving.push(self.p.parse_ident().as_str().to_string());
        }
        Ok(info)
    }
}

struct StructInfo {
    name: ast::Ident,
    public: bool,
    deriving: Vec<String>,
}

// Convenience functions for building intermediate values.

fn ident(s: &str) -> ast::Ident {
    ast::Ident::new(token::intern(s))
}

fn meta_item(cx: &ExtCtxt, s: &str) -> P<ast::MetaItem> {
    cx.meta_word(codemap::DUMMY_SP, intern(s))
}

fn intern(s: &str) -> token::InternedString {
    token::intern_and_get_ident(s)
}
<commit_msg>Update renamed token enum variants<commit_after>#![crate_name = "docopt_macros"]
#![crate_type = "dylib"]
#![feature(plugin_registrar, macro_rules, quote)]

extern crate syntax;
extern crate rustc;
extern crate docopt;

use std::collections::HashMap;

use rustc::plugin::Registry;
use syntax::ast;
use syntax::codemap;
use syntax::ext::base::{ExtCtxt, MacResult, MacItems, DummyResult};
use syntax::ext::build::AstBuilder;
use syntax::fold::Folder;
use syntax::parse::common::SeqSep;
use syntax::parse::parser::Parser;
use syntax::parse::token;
use syntax::print::pprust;
use syntax::ptr::P;

use docopt::{DEFAULT_CONFIG, Docopt, ValueMap};
use docopt::parse::{Options, Atom, Positional, Zero, One};

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("docopt", expand);
}

fn expand(cx: &mut ExtCtxt, span: codemap::Span, tts: &[ast::TokenTree])
         -> Box<MacResult+'static> {
    let parsed = match MacParser::new(cx, tts).parse() {
        Ok(parsed) => parsed,
        Err(_) => return DummyResult::any(span),
    };
    parsed.items(cx)
}

/// Parsed corresponds to the result of parsing a `docopt` macro call.
/// It can be used to write a corresponding struct.
struct Parsed {
    struct_info: StructInfo,
    doc: Docopt,
    /// Overrided type annotations for struct members. May be empty.
    /// When a type annotation for an atom doesn't exist, then one is
    /// inferred automatically. It is one of: `bool`, `uint`, `String` or
    /// `Vec<String>`.
    types: HashMap<Atom, P<ast::Ty>>,
}

impl Parsed {
    /// Returns a macro result suitable for expansion.
    /// Contains two items: one for the struct and one for the struct impls.
    fn items(&self, cx: &ExtCtxt) -> Box<MacResult+'static> {
        let mut its = vec!();
        its.push(self.struct_decl(cx));

        let struct_name = self.struct_info.name;
        let full_doc = self.doc.parser().full_doc.as_slice();
        its.push(quote_item!(cx,
            impl docopt::FlagParser for $struct_name {
                #[allow(dead_code)]
                fn parse_args(conf: docopt::Config, args: &[&str])
                             -> Result<$struct_name, docopt::Error> {
                    docopt::docopt_args(conf, args, $full_doc).and_then(|v| {
                        v.decode()
                    })
                }
            }
        ).unwrap());
        MacItems::new(its.into_iter())
    }

    /// Returns an item for the struct definition.
    fn struct_decl(&self, cx: &ExtCtxt) -> P<ast::Item> {
        let name = self.struct_info.name.clone();
        let vis = if self.struct_info.public { ast::Public }
                  else { ast::Inherited };
        let def = ast::StructDef {
            fields: self.struct_fields(cx),
            ctor_id: None
        };

        let sp = codemap::DUMMY_SP;
        let mut traits = vec![meta_item(cx, "Decodable")];
        for trait_name in self.struct_info.deriving.iter() {
            traits.push(meta_item(cx, trait_name.as_slice()));
        }
        let deriving = cx.meta_list(sp, intern("deriving"), traits);
        let attrs = vec![cx.attribute(codemap::DUMMY_SP, deriving)];
        let st = cx.item_struct(sp, name.clone(), def);
        cx.item(sp, name, attrs, st.node.clone()).map(|mut it| {
            it.vis = vis;
            it
        })
    }

    /// Returns a list of fields for the struct definition.
    /// Handles type annotations.
    fn struct_fields(&self, cx: &ExtCtxt) -> Vec<ast::StructField> {
        let mut fields: Vec<ast::StructField> = vec!();
        for (atom, opts) in self.doc.parser().descs.iter() {
            let name = ValueMap::key_to_struct_field(atom.to_string().as_slice());
            let ty = match self.types.find(atom) {
                None => self.pat_type(cx, atom, opts),
                Some(ty) => ty.clone(),
            };
            fields.push(self.mk_struct_field(name.as_slice(), ty));
        }
        fields
    }

    /// Returns an inferred type for a usage pattern.
    /// This is only invoked when a type annotation is not present.
    fn pat_type(&self, cx: &ExtCtxt, atom: &Atom, opts: &Options) -> P<ast::Ty> {
        match (opts.repeats, &opts.arg) {
            (false, &Zero) => {
                match atom {
                    &Positional(_) => quote_ty!(cx, String),
                    _ => quote_ty!(cx, bool),
                }
            }
            (true, &Zero) => {
                match atom {
                    &Positional(_) => quote_ty!(cx, Vec<String>),
                    _ => quote_ty!(cx, uint),
                }
            }
            (false, &One(_)) => quote_ty!(cx, String),
            (true, &One(_)) => quote_ty!(cx, Vec<String>),
        }
    }

    /// Creates a struct field from a member name and type.
    fn mk_struct_field(&self, name: &str, ty: P<ast::Ty>) -> ast::StructField {
        codemap::dummy_spanned(ast::StructField_ {
            kind: ast::NamedField(ident(name), ast::Public),
            id: ast::DUMMY_NODE_ID,
            ty: ty,
            attrs: vec!(),
        })
    }
}

/// State for parsing a `docopt` macro invocation.
struct MacParser<'a, 'b:'a> {
    cx: &'a mut ExtCtxt<'b>,
    p: Parser<'b>,
}

impl<'a, 'b> MacParser<'a, 'b> {
    fn new(cx: &'a mut ExtCtxt<'b>, tts: &[ast::TokenTree]) -> MacParser<'a, 'b> {
        let p = cx.new_parser_from_tts(tts);
        MacParser { cx: cx, p: p }
    }

    /// Main entry point for parsing arguments to `docopt` macro.
    /// First looks for an identifier for the struct name.
    /// Second, a string containing the docopt usage patterns.
    /// Third, an optional list of type annotations.
    fn parse(&mut self) -> Result<Parsed, ()> {
        if self.p.token == token::Eof {
            self.cx.span_err(self.cx.call_site(), "macro expects arguments");
            return Err(());
        }
        let struct_info = try!(self.parse_struct_info());
        let docstr = try!(self.parse_str());

        let sep = SeqSep {
            sep: Some(token::Comma),
            trailing_sep_allowed: true,
        };
        let types = self.p.parse_seq_to_end(
            &token::Eof, sep, |p| MacParser::parse_type_annotation(p)
        ).into_iter()
         .map(|(ident, ty)| {
             let field_name = token::get_ident(ident).to_string();
             let key = ValueMap::struct_field_to_key(field_name.as_slice());
             (Atom::new(key.as_slice()), ty)
          })
         .collect::<HashMap<Atom, P<ast::Ty>>>();
        self.p.expect(&token::Eof);

        // This config does not matter because we're only asking for the
        // usage patterns in the Docopt string. The configuration does not
        // affect the retrieval of usage patterns.
        let doc = match Docopt::new(DEFAULT_CONFIG.clone(), docstr.as_slice()) {
            Ok(doc) => doc,
            Err(err) => {
                self.cx.span_err(self.cx.call_site(),
                                 format!("Invalid Docopt usage: {}",
                                         err).as_slice());
                return Err(());
            }
        };
        Ok(Parsed {
            struct_info: struct_info,
            doc: doc,
            types: types,
        })
    }

    /// Parses a single string literal. On failure, an error is logged and
    /// unit is returned.
    fn parse_str(&mut self) -> Result<String, ()> {
        fn lit_is_str(lit: &ast::Lit) -> bool {
            match lit.node {
                ast::LitStr(_, _) => true,
                _ => false,
            }
        }
        fn lit_to_string(lit: &ast::Lit) -> String {
            match lit.node {
                ast::LitStr(ref s, _) => s.to_string(),
                _ => panic!("BUG: expected string literal"),
            }
        }
        let exp = self.cx.expander().fold_expr(self.p.parse_expr());
        let s = match exp.node {
            ast::ExprLit(ref lit) if lit_is_str(&**lit) => {
                lit_to_string(&**lit)
            }
            _ => {
                let err = format!("Expected string literal but got {}",
                                  pprust::expr_to_string(&*exp));
                self.cx.span_err(exp.span, err.as_slice());
                return Err(());
            }
        };
        self.p.bump();
        Ok(s)
    }

    /// Parses a type annotation in a `docopt` invocation of the form
    /// `ident: Ty`.
    /// Note that this is a static method as it is used as a HOF.
    fn parse_type_annotation(p: &mut Parser) -> (ast::Ident, P<ast::Ty>) {
        let ident = p.parse_ident();
        p.expect(&token::Colon);
        let ty = p.parse_ty(false);
        (ident, ty)
    }

    /// Parses struct information, like visibility, name and deriving.
    fn parse_struct_info(&mut self) -> Result<StructInfo, ()> {
        let public = self.p.eat_keyword(token::keywords::Pub);
        let mut info = StructInfo {
            name: self.p.parse_ident(),
            public: public,
            deriving: vec![],
        };
        if self.p.eat(&token::Comma) { return Ok(info); }
        let deriving = self.p.parse_ident();
        if deriving.as_str() != "deriving" {
            let err = format!("Expected 'deriving' keyword but got '{}'",
                              deriving);
            self.cx.span_err(self.cx.call_site(), err.as_slice());
            return Err(());
        }
        while !self.p.eat(&token::Comma) {
            info.deriving.push(self.p.parse_ident().as_str().to_string());
        }
        Ok(info)
    }
}

struct StructInfo {
    name: ast::Ident,
    public: bool,
    deriving: Vec<String>,
}

// Convenience functions for building intermediate values.

fn ident(s: &str) -> ast::Ident {
    ast::Ident::new(token::intern(s))
}

fn meta_item(cx: &ExtCtxt, s: &str) -> P<ast::MetaItem> {
    cx.meta_word(codemap::DUMMY_SP, intern(s))
}

fn intern(s: &str) -> token::InternedString {
    token::intern_and_get_ident(s)
}
<|endoftext|>


<commit_before>use super::Opcode;
use utils::u256::U256;
use vm::{Machine, Memory, Stack, PC};

// TODO: deal with gas limit and other Ethereum-specific things.

fn signed_abs(v: U256) -> U256 {
    let negative: U256 = U256::one() << 256;

    if v >= negative {
        !v + 1.into()
    } else {
        v
    }
}

impl Opcode {
    pub fn run<M: Memory, S: Stack>(&self, machine: &mut Machine<M, S>) {
        let pc = &mut machine.pc;
        let memory = &mut machine.memory;
        let stack = &mut machine.stack;
        let opcode = self.clone();

        match opcode {
            Opcode::STOP => {
                pc.stop();
            },

            Opcode::ADD => {
                let op1 = stack.pop();
                let op2 = stack.pop();
                stack.push(op1 + op2);
            },

            Opcode::MUL => {
                let op1 = stack.pop();
                let op2 = stack.pop();
                stack.push(op1 * op2);
            },

            Opcode::SUB => {
                let op1 = stack.pop();
                let op2 = stack.pop();
                stack.push(op1 - op2);
            },

            Opcode::DIV => {
                let op1 = stack.pop();
                let op2 = stack.pop();
                if op2 == 0.into() {
                    stack.push(0.into());
                } else {
                    stack.push(op1 / op2);
                }
            },

            Opcode::SDIV => {
                // This is signed division. So the U256 would need to
                // be treated as signed two's complement. We currently
                // convert it to both positive, and then deal with the
                // sign afterwards...

                let negative: U256 = U256::one() << 256;
                // This value is also -2^255 in two's complement.
                let max: U256 = U256::max_value();
                // This value is also -1 in two's complement.

                let op1 = stack.pop();
                let op2 = stack.pop();
                if op2 == 0.into() {
                    stack.push(0.into());
                } else if op1 == negative && op2 == max {
                    stack.push(negative);
                } else {
                    let aop1 = signed_abs(op1);
                    let aop2 = signed_abs(op2);
                    let r = op1 / op2;

                    if (op1 < negative && op2 < negative) || (op1 >= negative && op2 >= negative) {
                        stack.push(r);
                    } else {
                        let sr = !r + 1.into();
                        stack.push(sr);
                    }
                }
            },

            Opcode::GT => {
                let op1 = stack.pop();
                let op2 = stack.pop();
                if op1 > op2 {
                    stack.push(op1);
                } else {
                    stack.push(op2);
                }
            }

            Opcode::LT => {
                let op1 = stack.pop();
                let op2 = stack.pop();
                if op1 < op2 {
                    stack.push(op1);
                } else {
                    stack.push(op2);
                }
            }

            // TODO: implement omitted opcodes.

            Opcode::PUSH(v) => {
                let val = pc.read(v);
                stack.push(val);
            },

            _ => {
                unimplemented!();
            }
        }
    }
}
<commit_msg>Problem: MOD and SMOD is not implemented. Solution: Implement them!<commit_after>use super::Opcode;
use utils::u256::U256;
use vm::{Machine, Memory, Stack, PC};

// TODO: deal with gas limit and other Ethereum-specific things.

fn signed_abs(v: U256) -> U256 {
    let negative: U256 = U256::one() << 256;

    if v >= negative {
        !v + 1.into()
    } else {
        v
    }
}

impl Opcode {
    pub fn run<M: Memory, S: Stack>(&self, machine: &mut Machine<M, S>) {
        let pc = &mut machine.pc;
        let memory = &mut machine.memory;
        let stack = &mut machine.stack;
        let opcode = self.clone();

        match opcode {
            Opcode::STOP => {
                pc.stop();
            },

            Opcode::ADD => {
                let op1 = stack.pop();
                let op2 = stack.pop();
                stack.push(op1 + op2);
            },

            Opcode::MUL => {
                let op1 = stack.pop();
                let op2 = stack.pop();
                stack.push(op1 * op2);
            },

            Opcode::SUB => {
                let op1 = stack.pop();
                let op2 = stack.pop();
                stack.push(op1 - op2);
            },

            Opcode::DIV => {
                let op1 = stack.pop();
                let op2 = stack.pop();
                if op2 == 0.into() {
                    stack.push(0.into());
                } else {
                    stack.push(op1 / op2);
                }
            },

            Opcode::SDIV => {
                // This is signed division. So the U256 would need to
                // be treated as signed two's complement. We currently
                // convert it to both positive, and then deal with the
                // sign afterwards...

                let negative: U256 = U256::one() << 256;
                // This value is also -2^255 in two's complement.
                let max: U256 = U256::max_value();
                // This value is also -1 in two's complement.

                let op1 = stack.pop();
                let op2 = stack.pop();
                if op2 == 0.into() {
                    stack.push(0.into());
                } else if op1 == negative && op2 == max {
                    stack.push(negative);
                } else {
                    let aop1 = signed_abs(op1);
                    let aop2 = signed_abs(op2);
                    let r = op1 / op2;

                    if (op1 < negative && op2 < negative) || (op1 >= negative && op2 >= negative) {
                        stack.push(r);
                    } else {
                        let sr = !r + 1.into();
                        stack.push(sr);
                    }
                }
            },

            Opcode::MOD => {
                let op1 = stack.pop();
                let op2 = stack.pop();

                if op2 == 0.into() {
                    stack.push(0.into());
                } else {
                    stack.push(op1 - (op1 / op2) * op2);
                }
            },

            Opcode::SMOD => {
                let negative: U256 = U256::one() << 256;

                let op1 = stack.pop();
                let op2 = stack.pop();

                if op2 == 0.into() {
                    stack.push(0.into());
                } else {
                    let aop1 = signed_abs(op1);
                    let aop2 = signed_abs(op2);
                    let r = aop1 - (aop1 / aop2) * aop2;
                    if op1 < negative && op2 < negative {
                        stack.push(r);
                    } else if op1 >= negative && op2 < negative {
                        stack.push(!(op1 + r) + 1.into());
                    } else if op1 < negative && op2 >= negative {
                        stack.push(op1 + r);
                    } else if op1 >= negative && op2 >= negative {
                        stack.push(!r + 1.into());
                    }
                }
            },

            Opcode::GT => {
                let op1 = stack.pop();
                let op2 = stack.pop();
                if op1 > op2 {
                    stack.push(op1);
                } else {
                    stack.push(op2);
                }
            }

            Opcode::LT => {
                let op1 = stack.pop();
                let op2 = stack.pop();
                if op1 < op2 {
                    stack.push(op1);
                } else {
                    stack.push(op2);
                }
            }

            // TODO: implement omitted opcodes.

            Opcode::PUSH(v) => {
                let val = pc.read(v);
                stack.push(val);
            },

            _ => {
                unimplemented!();
            }
        }
    }
}
<|endoftext|>


<commit_before>//
// zhttpto.rs
//
// Starting code for PS1
// Running on Rust 0.9
//
// Note that this code has serious security risks!  You should not run it
// on any system with access to sensitive files.
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu and David Evans
// Version 0.3

#[feature(globs)];
use std::io::*;
use std::io::net::ip::{SocketAddr};
use std::{str};

static IP: &'static str = "127.0.0.1";
static PORT:        int = 4414;
static mut count:   int = 0;

fn main() {
    let addr = from_str::<SocketAddr>(format!("{:s}:{:d}", IP, PORT)).unwrap();
    let mut acceptor = net::tcp::TcpListener::bind(addr).listen();

    println(format!("Listening on [{:s}] ...", addr.to_str()));

    for stream in acceptor.incoming() {
        // Spawn a task to handle the connection
        do spawn {
            let mut stream = stream;

            match stream {
                Some(ref mut s) => {
                             match s.peer_name() {
                                Some(pn) => {
					println(format!("Received connection from: [{:s}]", pn.to_str()));
					unsafe {
						count = count + 1;
						println!("Total number of requests received: {:d}", count)
					}
				},
                                None => ()
                             }
                           },
                None => ()
            }

            let mut buf = [0, ..500];
            stream.read(buf);
            let request_str = str::from_utf8(buf);
            println(format!("Received request :\n{:s}", request_str));
            let mut components : ~[~str] = ~[];
            for tempString in request_str.split(' ') {
            	components.push(tempString.to_owned());
            }
            if !str::eq(&components[1], &~"/") {
        	let f1name = components[1].slice_from(1);
        	let path1 = Path::new(f1name.clone());
        	let mut msg_file1 = File::open(&path1);
                let msg_bytes1: ~[u8] = msg_file1.read_to_end();
		stream.write(msg_bytes1);
            }
            else {
            unsafe {
            let response: ~str =
                 ("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
                 <doctype !html><title>Hello, Rust!</title>

Greetings, Krusty!

" + format!("Total Number of Requests: {:d}
", count) +
                 "\r\n");
            stream.write(response.as_bytes());
            }
            println!("Connection terminates.");
            }
        }
    }
}
<commit_msg>Now only .html files are served<commit_after>//
// zhttpto.rs
//
// Starting code for PS1
// Running on Rust 0.9
//
// Note that this code has serious security risks!  You should not run it
// on any system with access to sensitive files.
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu and David Evans
// Version 0.3

#[feature(globs)];
use std::io::*;
use std::io::net::ip::{SocketAddr};
use std::{str};

static IP: &'static str = "127.0.0.1";
static PORT:        int = 4414;
static mut count:   int = 0;

fn main() {
    let addr = from_str::<SocketAddr>(format!("{:s}:{:d}", IP, PORT)).unwrap();
    let mut acceptor = net::tcp::TcpListener::bind(addr).listen();

    println(format!("Listening on [{:s}] ...", addr.to_str()));

    for stream in acceptor.incoming() {
        // Spawn a task to handle the connection
        do spawn {
            let mut stream = stream;

            match stream {
                Some(ref mut s) => {
                             match s.peer_name() {
                                Some(pn) => {
					println(format!("Received connection from: [{:s}]", pn.to_str()));
					unsafe {
						count = count + 1;
						println!("Total number of requests received: {:d}", count)
					}
				},
                                None => ()
                             }
                           },
                None => ()
            }

            let mut buf = [0, ..500];
            stream.read(buf);
            let request_str = str::from_utf8(buf);
            println(format!("Received request :\n{:s}", request_str));
            let mut components : ~[~str] = ~[];
            for tempString in request_str.split(' ') {
            	components.push(tempString.to_owned());
            }
            if !str::eq(&components[1], &~"/") {
            	if components[1].len() > 4 && str::eq(&components[1].slice_from(components[1].len()-5).to_owned(), &~".html") {
        	let f1name = components[1].slice_from(1);
        	let path1 = Path::new(f1name.clone());
        	let mut msg_file1 = File::open(&path1);
                let msg_bytes1: ~[u8] = msg_file1.read_to_end();
		stream.write(msg_bytes1);
		}
		else {
            let response: ~str =
                 ~"HTTP/1.1 403 Forbidden\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
                 <doctype !html><title>403 Forbidden</title>

403: Forbidden

You do not have permission to access that file";
		stream.write(response.as_bytes());
		}
            }
            else {
            unsafe {
            let response: ~str =
                 ("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
                 <doctype !html><title>Hello, Rust!</title>

Greetings, Krusty!

" + format!("Total Number of Requests: {:d}
", count) +
                 "\r\n");
            stream.write(response.as_bytes());
            }
            println!("Connection terminates.");
            }
        }
    }
}
<|endoftext|>


<commit_before>#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
where
    Storage: AsRef<[u8]> + AsMut<[u8]>,
{
    storage: Storage,
    align: [Align; 0],
}

impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align>
where
    Storage: AsRef<[u8]> + AsMut<[u8]>,
{
    #[inline]
    pub fn new(storage: Storage) -> Self {
        Self {
            storage,
            align: [],
        }
    }

    #[inline]
    pub fn get_bit(&self, index: usize) -> bool {
        debug_assert!(index / 8 < self.storage.as_ref().len());

        let byte_index = index / 8;
        let byte = self.storage.as_ref()[byte_index];

        let mut bit_index = index % 8;
        #[cfg(target_endian = "big")]
        {
            // Adjust the index for endianness.
            bit_index = 7 - bit_index;
        }
        let mask = 1 << bit_index;

        byte & mask == mask
    }

    #[inline]
    pub fn set_bit(&mut self, index: usize, val: bool) {
        debug_assert!(index / 8 < self.storage.as_ref().len());

        let byte_index = index / 8;
        let byte = &mut self.storage.as_mut()[byte_index];

        let mut bit_index = index % 8;
        #[cfg(target_endian = "big")]
        {
            // Adjust the index for endianness.
            bit_index = 7 - bit_index;
        }
        let mask = 1 << bit_index;

        if val {
            *byte |= mask;
        } else {
            *byte &= !mask;
        }
    }

    #[inline]
    pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 {
        debug_assert!(bit_width <= 64);
        debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
        debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());

        let mut val = 0;

        for i in 0..(bit_width as usize) {
            if self.get_bit(i + bit_offset) {
                let mut index  = i;
                #[cfg(target_endian = "big")]
                {
                   // Adjust the index for endianness.
                   index  = bit_width as usize - 1 - index;
                }
                val |= 1 << index;
            }
        }

        val
    }

    #[inline]
    pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) {
        debug_assert!(bit_width <= 64);
        debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
        debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());

        for i in 0..(bit_width as usize) {
            let mask = 1 << i;
            let val_bit_is_set = val & mask == mask;
            let mut index  = i;
            #[cfg(target_endian = "big")]
            {
                // Adjust the index for endianness.
                index  = bit_width as usize - 1 - index;
            }
            self.set_bit(index + bit_offset, val_bit_is_set);
        }
    }
}
<commit_msg>codegen: Prevent unused_mut warnings, and fix formatting issues.<commit_after>#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
where
    Storage: AsRef<[u8]> + AsMut<[u8]>,
{
    storage: Storage,
    align: [Align; 0],
}

impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align>
where
    Storage: AsRef<[u8]> + AsMut<[u8]>,
{
    #[inline]
    pub fn new(storage: Storage) -> Self {
        Self {
            storage,
            align: [],
        }
    }

    #[inline]
    pub fn get_bit(&self, index: usize) -> bool {
        debug_assert!(index / 8 < self.storage.as_ref().len());

        let byte_index = index / 8;
        let byte = self.storage.as_ref()[byte_index];

        let bit_index =
            if cfg!(target_endian = "big") {
                7 - (index % 8)
            } else {
                index % 8
            };

        let mask = 1 << bit_index;

        byte & mask == mask
    }

    #[inline]
    pub fn set_bit(&mut self, index: usize, val: bool) {
        debug_assert!(index / 8 < self.storage.as_ref().len());

        let byte_index = index / 8;
        let byte = &mut self.storage.as_mut()[byte_index];

        let bit_index =
            if cfg!(target_endian = "big") {
                7 - (index % 8)
            } else {
                index % 8
            };

        let mask = 1 << bit_index;
        if val {
            *byte |= mask;
        } else {
            *byte &= !mask;
        }
    }

    #[inline]
    pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 {
        debug_assert!(bit_width <= 64);
        debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
        debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());

        let mut val = 0;

        for i in 0..(bit_width as usize) {
            if self.get_bit(i + bit_offset) {
                let index =
                    if cfg!(target_endian = "big") {
                        bit_width as usize - 1 - i
                    } else {
                        i
                    };
                val |= 1 << index;
            }
        }

        val
    }

    #[inline]
    pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) {
        debug_assert!(bit_width <= 64);
        debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
        debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());

        for i in 0..(bit_width as usize) {
            let mask = 1 << i;
            let val_bit_is_set = val & mask == mask;
            let index =
                if cfg!(target_endian = "big") {
                    bit_width as usize - 1 - i
                } else {
                    i
                };
            self.set_bit(index + bit_offset, val_bit_is_set);
        }
    }
}
<|endoftext|>


<commit_before>extern mod extra;
use std::os;
use std::path;
use std::io;
use extra::getopts::*;

fn print_usage(program_name: &str, _opts: &[Opt]) {
	println(fmt!("Usage: %s [options]", program_name));
	println("  -i\t\t-> Path to input file");
	println("  -h | -help\t-> Print this help message");
}

fn load(file: &path::Path) -> ~[~str] {

	let read_result = io::file_reader(file);
	if read_result.is_ok() {
		return read_result.unwrap().read_lines();
	}

	fail!(fmt!("Error reading input grid file: %?", read_result.unwrap_err()));
}

fn main() {

	let args : ~[~str] = os::args();

	let opts = ~[
		reqopt("i"),
		optflag("h"),
		optflag("help")
	];

	let program_name: ~str = args[0].clone();

	let opt_matches = match getopts(args.tail(), opts) {
		Ok(m) => { m }
		Err(f) => {
			print_usage(program_name, opts);
			println("");
			fail!(fail_str(f))
		}
	};

	if opt_present(&opt_matches, "h") || opt_present(&opt_matches, "help") {
		print_usage(program_name, opts);
		return;
	}

	let input: &str = opt_str(&opt_matches, "i");
	let input_path = ~path::Path(input);
	let grid: ~[~str] = load(input_path);

	for grid.iter().advance() |line| {
		println(*line);
	}
}<commit_msg>Convert input to 2d array<commit_after>extern mod extra;
use std::os;
use std::path;
use std::io;
use extra::getopts::*;

fn print_usage(program_name: &str, _opts: &[Opt]) {
	println(fmt!("Usage: %s [options]", program_name));
	println("  -i\t\t-> Path to input file");
	println("  -h | -help\t-> Print this help message");
}

/**
* Loads the input grid file.
* File format is line delmited '0's and '1's.
* 1 = The square is true|on in the game of life.
* 0 = The square is false|off in the game of life.
**/
fn load(file: &path::Path) -> ~[~[bool]] {

	let read_result = io::file_reader(file);

	let lines = match read_result {
		Ok(file) => file.read_lines(),
		Err(e) => {
			fail!(fmt!("Error reading input grid file: %?", e))
		}
	};

	let mut grid: ~[~[bool]] = ~[];

	for lines.iter().advance() |line: &~str| {
		let mut next: ~[bool] = ~[];
		for line.iter().advance() |c| {
			let b: bool = match c {
				'0' => false,
				'1' => true,
				_ => fail!(fmt!("Error parsing input grid file: %c is not valid, 0 or 1 only.", c))
			};
			next.push(b)
		}
		grid.push(next);
	}

	return grid;
}

fn print_grid(grid: ~[~[bool]]) {
	for grid.iter().advance() |row| {
		for row.iter().advance() |b| {
			print(fmt!("%c", match b {
				&false => '0',
				&true => '1'
			}));
		}
		println("");
	}
}

fn main() {

	let args : ~[~str] = os::args();

	let opts = ~[
		reqopt("i"),
		optflag("h"),
		optflag("help")
	];

	let program_name: ~str = args[0].clone();

	let opt_matches = match getopts(args.tail(), opts) {
		Ok(m) => { m }
		Err(f) => {
			print_usage(program_name, opts);
			println("");
			fail!(fail_str(f))
		}
	};

	if opt_present(&opt_matches, "h") || opt_present(&opt_matches, "help") {
		print_usage(program_name, opts);
		return;
	}

	let input: &str = opt_str(&opt_matches, "i");
	let input_path = ~path::Path(input);
	let grid: ~[~[bool]] = load(input_path);
	print_grid(grid);
}<|endoftext|>


<commit_before>use std::error::Error;
use std::fmt;

use ggez::Context;
use ron;
use warmy;
use warmy::{Load, SimpleKey, StoreErrorOr};

use crate::animation::{Sprite, SpriteData};
use crate::campaign::movement_cost::CampaignMap;
use crate::files::collide::CollideHitParseError;
use crate::objects::{TextureAtlas, TextureSizeTooSmall};
use crate::piv::PivImage;
use crate::ron::{FromRon, GameRon, Files};
use crate::scenes::map::{FileList, Locations, MapData};

#[derive(Debug)]
pub enum MoonstoneError {
    Io(std::io::Error),
    Map(StoreErrorOr<MapData, Context, SimpleKey>),
    Piv(StoreErrorOr<PivImage, Context, SimpleKey>),
    Sprite(StoreErrorOr<Sprite, Context, SimpleKey>),
    TextureAtlas(StoreErrorOr<TextureAtlas, Context, SimpleKey>),
    Ron(StoreErrorOr<GameRon<CampaignMap>, Context, SimpleKey, FromRon>),
    FileList(StoreErrorOr<GameRon<FileList>, Context, SimpleKey, FromRon>),
    Locations(StoreErrorOr<GameRon<Locations>, Context, SimpleKey, FromRon>),
    SpriteRon(StoreErrorOr<GameRon<Sprite>, Context, SimpleKey, FromRon>),
    SpriteData(StoreErrorOr<GameRon<SpriteData>, Context, SimpleKey, FromRon>),
    FilesRon(StoreErrorOr<GameRon<Files>, Context, SimpleKey, FromRon>),
    Ggez(ggez::error::GameError),
    PathLoadNotImplemented,
    NotInDosFiles,
}

impl Error for MoonstoneError {}

impl fmt::Display for MoonstoneError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            MoonstoneError::Io(ref err) => err.fmt(f),
            MoonstoneError::Map(ref err) => err.fmt(f),
            MoonstoneError::Piv(ref err) => err.fmt(f),
            MoonstoneError::Sprite(ref err) => err.fmt(f),
            MoonstoneError::TextureAtlas(ref err) => err.fmt(f),
            MoonstoneError::Ron(ref err) => err.fmt(f),
            MoonstoneError::FileList(ref err) => err.fmt(f),
            MoonstoneError::Locations(ref err) => err.fmt(f),
            MoonstoneError::SpriteRon(ref err) => err.fmt(f),
            MoonstoneError::SpriteData(ref err) => err.fmt(f),
            MoonstoneError::FilesRon(ref err) => err.fmt(f),
            MoonstoneError::Ggez(ref err) => err.fmt(f),
            MoonstoneError::PathLoadNotImplemented => write!(f, "Path not implemented"),
            MoonstoneError::NotInDosFiles => write!(f, "File not found in dos_files.ron"),
        }
    }
}

impl From<std::io::Error> for MoonstoneError {
    fn from(err: std::io::Error) -> MoonstoneError {
        MoonstoneError::Io(err)
    }
}

impl From<StoreErrorOr<MapData, Context, SimpleKey>> for MoonstoneError {
    fn from(err: StoreErrorOr<MapData, Context, SimpleKey>) -> MoonstoneError {
        MoonstoneError::Map(err)
    }
}

impl From<StoreErrorOr<GameRon<CampaignMap>, Context, SimpleKey, FromRon>> for MoonstoneError {
    fn from(
        err: StoreErrorOr<GameRon<CampaignMap>, Context, SimpleKey, FromRon>,
    ) -> MoonstoneError {
        MoonstoneError::Ron(err)
    }
}

impl From<StoreErrorOr<GameRon<FileList>, Context, SimpleKey, FromRon>> for MoonstoneError {
    fn from(err: StoreErrorOr<GameRon<FileList>, Context, SimpleKey, FromRon>) -> MoonstoneError {
        MoonstoneError::FileList(err)
    }
}

impl From<StoreErrorOr<GameRon<Locations>, Context, SimpleKey, FromRon>> for MoonstoneError {
    fn from(err: StoreErrorOr<GameRon<Locations>, Context, SimpleKey, FromRon>) -> MoonstoneError {
        MoonstoneError::Locations(err)
    }
}

impl From<StoreErrorOr<GameRon<Sprite>, Context, SimpleKey, FromRon>> for MoonstoneError {
    fn from(err: StoreErrorOr<GameRon<Sprite>, Context, SimpleKey, FromRon>) -> MoonstoneError {
        MoonstoneError::SpriteRon(err)
    }
}

impl From<StoreErrorOr<GameRon<SpriteData>, Context, SimpleKey, FromRon>> for MoonstoneError {
    fn from(err: StoreErrorOr<GameRon<SpriteData>, Context, SimpleKey, FromRon>) -> MoonstoneError {
        MoonstoneError::SpriteData(err)
    }
}

impl From<StoreErrorOr<GameRon<Files>, Context, SimpleKey, FromRon>> for MoonstoneError {
    fn from(err: StoreErrorOr<GameRon<Files>, Context, SimpleKey, FromRon>) -> MoonstoneError {
        MoonstoneError::FilesRon(err)
    }
}

impl From<StoreErrorOr<PivImage, Context, SimpleKey>> for MoonstoneError {
    fn from(err: StoreErrorOr<PivImage, Context, SimpleKey>) -> MoonstoneError {
        MoonstoneError::Piv(err)
    }
}

impl From<StoreErrorOr<Sprite, Context, SimpleKey>> for MoonstoneError {
    fn from(err: StoreErrorOr<Sprite, Context, SimpleKey>) -> MoonstoneError {
        MoonstoneError::Sprite(err)
    }
}

impl From<StoreErrorOr<TextureAtlas, Context, SimpleKey>> for MoonstoneError {
    fn from(err: StoreErrorOr<TextureAtlas, Context, SimpleKey>) -> MoonstoneError {
        MoonstoneError::TextureAtlas(err)
    }
}

impl From<ggez::error::GameError> for MoonstoneError {
    fn from(err: ggez::error::GameError) -> MoonstoneError {
        MoonstoneError::Ggez(err)
    }
}

#[derive(Debug)]
pub enum BaseLoadError {
    Io(std::io::Error),
    Ggez(ggez::error::GameError),
    Serde(serde_yaml::Error),
    RonDeserialize(ron::de::Error),
    PathLoadNotImplemented,
}

impl Error for BaseLoadError {}

impl fmt::Display for BaseLoadError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            BaseLoadError::Io(ref err) => err.fmt(f),
            BaseLoadError::Ggez(ref err) => err.fmt(f),
            BaseLoadError::Serde(ref err) => err.fmt(f),
            BaseLoadError::PathLoadNotImplemented => write!(f, "Path not implemented"),
            BaseLoadError::RonDeserialize(ref err) => err.fmt(f),
        }
    }
}

impl From<ggez::error::GameError> for BaseLoadError {
    fn from(err: ggez::error::GameError) -> BaseLoadError {
        BaseLoadError::Ggez(err)
    }
}

impl From<serde_yaml::Error> for BaseLoadError {
    fn from(err: serde_yaml::Error) -> BaseLoadError {
        BaseLoadError::Serde(err)
    }
}

impl From<std::io::Error> for BaseLoadError {
    fn from(err: std::io::Error) -> BaseLoadError {
        BaseLoadError::Io(err)
    }
}

impl From<ron::de::Error> for BaseLoadError {
    fn from(err: ron::de::Error) -> BaseLoadError {
        BaseLoadError::RonDeserialize(err)
    }
}

#[derive(Debug)]
pub enum LoadError<T>
where
    T: Load<Context, SimpleKey>,
    T::Error: fmt::Debug,
{
    Io(std::io::Error),
    Ggez(ggez::error::GameError),
    Serde(serde_yaml::Error),
    Warmy(warmy::load::StoreErrorOr<T, Context, SimpleKey>),
    PathLoadNotImplemented,
    YamlKeyDoesNotExist { key: String },
    TextureSizeTooSmall(TextureSizeTooSmall),
    CollideHit(CollideHitParseError),
}

impl<T> fmt::Display for LoadError<T>
where
    T: Load<Context, SimpleKey> + fmt::Display,
    T::Error: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            LoadError::Io(ref err) => err.fmt(f),
            LoadError::Ggez(ref err) => err.fmt(f),
            LoadError::Serde(ref err) => err.fmt(f),
            LoadError::Warmy(ref err) => err.fmt(f),
            LoadError::PathLoadNotImplemented => write!(f, "Path not implemented"),
            LoadError::YamlKeyDoesNotExist { ref key } => {
                write!(f, "Yaml key {} does not exist", key)
            }
            LoadError::TextureSizeTooSmall(ref err) => err.fmt(f),
            LoadError::CollideHit(ref err) => err.fmt(f),
        }
    }
}

impl<T> Error for LoadError<T>
where
    T: Load<Context, SimpleKey> + fmt::Display + fmt::Debug,
    T::Error: fmt::Debug,
{
}

impl<T> From<ggez::error::GameError> for LoadError<T>
where
    T: Load<Context, SimpleKey>,
    T::Error: fmt::Debug,
{
    fn from(err: ggez::error::GameError) -> LoadError<T> {
        LoadError::Ggez(err)
        // LoadError::Ggez { source: err }
    }
}

// impl From<serde_yaml::Error> for LoadError
impl<T> From<serde_yaml::Error> for LoadError<T>
where
    T: Load<Context, SimpleKey>,
    T::Error: fmt::Debug,
{
    fn from(err: serde_yaml::Error) -> LoadError<T> {
        // LoadError::Serde { source: err }
        LoadError::Serde(err)
    }
}

impl<T> From<std::io::Error> for LoadError<T>
where
    T: Load<Context, SimpleKey>,
    T::Error: fmt::Debug,
{
    fn from(err: std::io::Error) -> LoadError<T> {
        // LoadError::Io { source: err }
        LoadError::Io(err)
    }
}

impl<T> From<TextureSizeTooSmall> for LoadError<T>
where
    T: Load<Context, SimpleKey>,
    T::Error: fmt::Debug,
{
    fn from(err: TextureSizeTooSmall) -> LoadError<T> {
        LoadError::TextureSizeTooSmall(err)
    }
}

impl<T> From<CollideHitParseError> for LoadError<T>
where
    T: Load<Context, SimpleKey>,
    T::Error: fmt::Debug,
{
    fn from(err: CollideHitParseError) -> LoadError<T> {
        LoadError::CollideHit(err)
    }
}

// impl From<warmy::load::StoreErrorOr<GameYaml, Context, SimpleKey>> for LoadError
impl<T> From<warmy::load::StoreErrorOr<T, Context, SimpleKey>> for LoadError<T>
where
    T: Load<Context, SimpleKey>,
    T::Error: fmt::Debug,
{
    fn from(err: warmy::load::StoreErrorOr<T, Context, SimpleKey>) -> LoadError<T> {
        LoadError::Warmy(err)
    }
}
<commit_msg>error.rs handling<commit_after>use std::error::Error;
use std::fmt;

use ggez::Context;
use ron;
use warmy;
use warmy::{Load, SimpleKey, StoreErrorOr};

use crate::animation::{Sprite, SpriteData};
use crate::campaign::movement_cost::CampaignMap;
use crate::files::collide::CollideHitParseError;
use crate::objects::{TextureAtlas, TextureSizeTooSmall};
use crate::piv::PivImage;
use crate::ron::{Files, FromDosFilesRon, FromRon, GameRon};
use crate::scenes::map::{FileList, Locations, MapData};
use crate::text::Screen;

#[derive(Debug)]
pub enum MoonstoneError {
    Io(std::io::Error),
    Map(StoreErrorOr<MapData, Context, SimpleKey>),
    Piv(StoreErrorOr<PivImage, Context, SimpleKey>),
    Sprite(StoreErrorOr<Sprite, Context, SimpleKey>),
    TextureAtlas(StoreErrorOr<TextureAtlas, Context, SimpleKey>),
    TextureSizeTooSmall(TextureSizeTooSmall),
    Ron(StoreErrorOr<GameRon<CampaignMap>, Context, SimpleKey, FromRon>),
    FileList(StoreErrorOr<GameRon<FileList>, Context, SimpleKey, FromRon>),
    Locations(StoreErrorOr<GameRon<Locations>, Context, SimpleKey, FromRon>),
    ScreenRon(StoreErrorOr<Screen, Context, SimpleKey, FromRon>),
    SpriteRon(StoreErrorOr<GameRon<Sprite>, Context, SimpleKey, FromRon>),
    SpriteData(StoreErrorOr<GameRon<SpriteData>, Context, SimpleKey, FromRon>),
    FilesRon(StoreErrorOr<GameRon<Files>, Context, SimpleKey, FromRon>),
    Ggez(ggez::error::GameError),
    PathLoadNotImplemented,
    NotInDosFiles,
}

impl Error for MoonstoneError {}

impl fmt::Display for MoonstoneError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            MoonstoneError::Io(ref err) => err.fmt(f),
            MoonstoneError::Map(ref err) => err.fmt(f),
            MoonstoneError::Piv(ref err) => err.fmt(f),
            MoonstoneError::Sprite(ref err) => err.fmt(f),
            MoonstoneError::TextureAtlas(ref err) => err.fmt(f),
            MoonstoneError::TextureSizeTooSmall(ref err) => err.fmt(f),
            MoonstoneError::Ron(ref err) => err.fmt(f),
            MoonstoneError::FileList(ref err) => err.fmt(f),
            MoonstoneError::Locations(ref err) => err.fmt(f),
            MoonstoneError::ScreenRon(ref err) => err.fmt(f),
            MoonstoneError::SpriteRon(ref err) => err.fmt(f),
            MoonstoneError::SpriteData(ref err) => err.fmt(f),
            MoonstoneError::FilesRon(ref err) => err.fmt(f),
            MoonstoneError::Ggez(ref err) => err.fmt(f),
            MoonstoneError::PathLoadNotImplemented => write!(f, "Path not implemented"),
            MoonstoneError::NotInDosFiles => write!(f, "File not found in dos_files.ron"),
        }
    }
}

impl From<std::io::Error> for MoonstoneError {
    fn from(err: std::io::Error) -> MoonstoneError {
        MoonstoneError::Io(err)
    }
}

impl From<TextureSizeTooSmall> for MoonstoneError {
    fn from(err: TextureSizeTooSmall) -> MoonstoneError {
        MoonstoneError::TextureSizeTooSmall(err)
    }
}

impl From<StoreErrorOr<MapData, Context, SimpleKey>> for MoonstoneError {
    fn from(err: StoreErrorOr<MapData, Context, SimpleKey>) -> MoonstoneError {
        MoonstoneError::Map(err)
    }
}

impl From<StoreErrorOr<GameRon<CampaignMap>, Context, SimpleKey, FromRon>> for MoonstoneError {
    fn from(
        err: StoreErrorOr<GameRon<CampaignMap>, Context, SimpleKey, FromRon>,
    ) -> MoonstoneError {
        MoonstoneError::Ron(err)
    }
}

impl From<StoreErrorOr<GameRon<FileList>, Context, SimpleKey, FromRon>> for MoonstoneError {
    fn from(err: StoreErrorOr<GameRon<FileList>, Context, SimpleKey, FromRon>) -> MoonstoneError {
        MoonstoneError::FileList(err)
    }
}

impl From<StoreErrorOr<GameRon<Locations>, Context, SimpleKey, FromRon>> for MoonstoneError {
    fn from(err: StoreErrorOr<GameRon<Locations>, Context, SimpleKey, FromRon>) -> MoonstoneError {
        MoonstoneError::Locations(err)
    }
}

impl From<StoreErrorOr<Screen, Context, SimpleKey, FromRon>> for MoonstoneError {
    fn from(err: StoreErrorOr<Screen, Context, SimpleKey, FromRon>) -> MoonstoneError {
        MoonstoneError::ScreenRon(err)
    }
}

impl From<StoreErrorOr<GameRon<Sprite>, Context, SimpleKey, FromRon>> for MoonstoneError {
    fn from(err: StoreErrorOr<GameRon<Sprite>, Context, SimpleKey, FromRon>) -> MoonstoneError {
        MoonstoneError::SpriteRon(err)
    }
}

impl From<StoreErrorOr<GameRon<SpriteData>, Context, SimpleKey, FromRon>> for MoonstoneError {
    fn from(err: StoreErrorOr<GameRon<SpriteData>, Context, SimpleKey, FromRon>) -> MoonstoneError {
        MoonstoneError::SpriteData(err)
    }
}

impl From<StoreErrorOr<GameRon<Files>, Context, SimpleKey, FromRon>> for MoonstoneError {
    fn from(err: StoreErrorOr<GameRon<Files>, Context, SimpleKey, FromRon>) -> MoonstoneError {
        MoonstoneError::FilesRon(err)
    }
}

impl From<StoreErrorOr<PivImage, Context, SimpleKey>> for MoonstoneError {
    fn from(err: StoreErrorOr<PivImage, Context, SimpleKey>) -> MoonstoneError {
        MoonstoneError::Piv(err)
    }
}

impl From<StoreErrorOr<Sprite, Context, SimpleKey>> for MoonstoneError {
    fn from(err: StoreErrorOr<Sprite, Context, SimpleKey>) -> MoonstoneError {
        MoonstoneError::Sprite(err)
    }
}

impl From<StoreErrorOr<TextureAtlas, Context, SimpleKey>> for MoonstoneError {
    fn from(err: StoreErrorOr<TextureAtlas, Context, SimpleKey>) -> MoonstoneError {
        MoonstoneError::TextureAtlas(err)
    }
}

impl From<ggez::error::GameError> for MoonstoneError {
    fn from(err: ggez::error::GameError) -> MoonstoneError {
        MoonstoneError::Ggez(err)
    }
}

#[derive(Debug)]
pub enum BaseLoadError {
    Io(std::io::Error),
    Ggez(ggez::error::GameError),
    Serde(serde_yaml::Error),
    RonDeserialize(ron::de::Error),
    PathLoadNotImplemented,
}

impl Error for BaseLoadError {}

impl fmt::Display for BaseLoadError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            BaseLoadError::Io(ref err) => err.fmt(f),
            BaseLoadError::Ggez(ref err) => err.fmt(f),
            BaseLoadError::Serde(ref err) => err.fmt(f),
            BaseLoadError::PathLoadNotImplemented => write!(f, "Path not implemented"),
            BaseLoadError::RonDeserialize(ref err) => err.fmt(f),
        }
    }
}

impl From<ggez::error::GameError> for BaseLoadError {
    fn from(err: ggez::error::GameError) -> BaseLoadError {
        BaseLoadError::Ggez(err)
    }
}

impl From<serde_yaml::Error> for BaseLoadError {
    fn from(err: serde_yaml::Error) -> BaseLoadError {
        BaseLoadError::Serde(err)
    }
}

impl From<std::io::Error> for BaseLoadError {
    fn from(err: std::io::Error) -> BaseLoadError {
        BaseLoadError::Io(err)
    }
}

impl From<ron::de::Error> for BaseLoadError {
    fn from(err: ron::de::Error) -> BaseLoadError {
        BaseLoadError::RonDeserialize(err)
    }
}

#[derive(Debug)]
pub enum LoadError<T>
where
    T: Load<Context, SimpleKey>,
    T::Error: fmt::Debug,
{
    Io(std::io::Error),
    Ggez(ggez::error::GameError),
    Serde(serde_yaml::Error),
    Warmy(warmy::load::StoreErrorOr<T, Context, SimpleKey>),
    // WarmyFromDosFilesRon(warmy::load::StoreErrorOr<T, Context, SimpleKey, FromDosFilesRon>),
    PathLoadNotImplemented,
    YamlKeyDoesNotExist { key: String },
    TextureSizeTooSmall(TextureSizeTooSmall),
    CollideHit(CollideHitParseError),
}

impl<T> fmt::Display for LoadError<T>
where
    T: Load<Context, SimpleKey> + fmt::Display,
    T::Error: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            LoadError::Io(ref err) => err.fmt(f),
            LoadError::Ggez(ref err) => err.fmt(f),
            LoadError::Serde(ref err) => err.fmt(f),
            LoadError::Warmy(ref err) => err.fmt(f),
            // LoadError::WarmyFromDosFilesRon(ref err) => err.fmt(f),
            LoadError::PathLoadNotImplemented => write!(f, "Path not implemented"),
            LoadError::YamlKeyDoesNotExist { ref key } => {
                write!(f, "Yaml key {} does not exist", key)
            }
            LoadError::TextureSizeTooSmall(ref err) => err.fmt(f),
            LoadError::CollideHit(ref err) => err.fmt(f),
        }
    }
}

impl<T> Error for LoadError<T>
where
    T: Load<Context, SimpleKey> + fmt::Display + fmt::Debug,
    T::Error: fmt::Debug,
{
}

impl<T> From<ggez::error::GameError> for LoadError<T>
where
    T: Load<Context, SimpleKey>,
    T::Error: fmt::Debug,
{
    fn from(err: ggez::error::GameError) -> LoadError<T> {
        LoadError::Ggez(err)
        // LoadError::Ggez { source: err }
    }
}

// impl From<serde_yaml::Error> for LoadError
impl<T> From<serde_yaml::Error> for LoadError<T>
where
    T: Load<Context, SimpleKey>,
    T::Error: fmt::Debug,
{
    fn from(err: serde_yaml::Error) -> LoadError<T> {
        // LoadError::Serde { source: err }
        LoadError::Serde(err)
    }
}

impl<T> From<std::io::Error> for LoadError<T>
where
    T: Load<Context, SimpleKey>,
    T::Error: fmt::Debug,
{
    fn from(err: std::io::Error) -> LoadError<T> {
        // LoadError::Io { source: err }
        LoadError::Io(err)
    }
}

impl<T> From<TextureSizeTooSmall> for LoadError<T>
where
    T: Load<Context, SimpleKey>,
    T::Error: fmt::Debug,
{
    fn from(err: TextureSizeTooSmall) -> LoadError<T> {
        LoadError::TextureSizeTooSmall(err)
    }
}

impl<T> From<CollideHitParseError> for LoadError<T>
where
    T: Load<Context, SimpleKey>,
    T::Error: fmt::Debug,
{
    fn from(err: CollideHitParseError) -> LoadError<T> {
        LoadError::CollideHit(err)
    }
}

// impl From<warmy::load::StoreErrorOr<GameYaml, Context, SimpleKey>> for LoadError
impl<T> From<warmy::load::StoreErrorOr<T, Context, SimpleKey>> for LoadError<T>
where
    T: Load<Context, SimpleKey>,
    T::Error: fmt::Debug,
{
    fn from(err: warmy::load::StoreErrorOr<T, Context, SimpleKey>) -> LoadError<T> {
        LoadError::Warmy(err)
    }
}

// impl<T> From<warmy::load::StoreErrorOr<T, Context, SimpleKey, FromDosFilesRon>> for LoadError<T>
// where
//     T: Load<Context, SimpleKey, FromDosFilesRon>,
//     T::Error: fmt::Debug,
// {
//     fn from(err: warmy::load::StoreErrorOr<T, Context, SimpleKey, FromDosFilesRon>) -> LoadError<T> {
//         LoadError::WarmyFromDosFilesRon(err)
//     }
// }
<|endoftext|>


<commit_before>/// Empty trait to define an expression superclass.
pub trait Expr: Statement {}

#[derive(Debug)]
/// Unary Operators
pub enum UnaryOperator {
    Not,
    Negative,
}
impl Expr for UnaryOperator {}

/// Empty trait to help define BinaryOperator as a superclass.
pub trait BinaryOperator: Expr {}

#[derive(Debug)]
/// Binary Operators
pub enum ArithmeticOperator {
    Add,
    Subtract,
    Multiply,
    Divide,
    Modulo,
    BitwiseAnd,
    BitwiseOr,
    BitwiseXor,
    LeftShift,
    RightShift,
    Increment,
    Decrement,
}
impl BinaryOperator for ArithmeticOperator {}

#[derive(Debug)]
/// Logical Operators
pub enum LogicalOperator {
    And,
    Or,
    Xor,
    ShortAnd,
    ShortOr,
}
impl BinaryOperator for LogicalOperator {}

#[derive(Debug)]
/// Relational Operators
pub enum RelationalOperators {
    Equal,
    NotEqual,
    GreaterThan,
    LessThan,
    GreaterOrEqual,
    LessOrEqual,
}
impl BinaryOperator for RelationalOperators {}

#[derive(Debug)]
/// Unary Expression.
pub struct UnaryExpr {
    pub operator: UnaryOperator,
    pub left: Expr,
}
impl Expr for UnaryExpr {}

#[derive(Debug)]
/// Binary Expression.
pub struct BinaryExpr{
    pub left: Expr,
    pub operator: BinaryOperator,
    pub right: Expr,
}
impl Expr for BinaryExpr {}

#[derive(Debug)]
/// Literal struct.
pub struct Literal {
    /// For type inference, when and where possible.
    pub literal_type: Option<String>,
    pub literal: String,
}
impl Expr for Literal {}

#[derive(Debug)]
/// Identifier struct.
pub struct Identifier {
    pub id: String,
}
impl Expr for Identifier {}

#[derive(Debug)]
/// Function call.
pub struct Call {
    pub callee: String,
    pub args: Vec<Expr>,
}
impl Expr for Call {}

/// Empty trait for statements.
pub trait Statement {}

#[derive(Debug)]
/// Different types of assignments, one for mutability, the other for immutability.
pub enum Assign {
    Let,
    Var,
}

#[derive(Debug)]
/// Assignment statement.
pub struct Assignment {
    pub left: Identifier,
    pub assign_type: Assign,
    pub right: Expr,
}
impl Statement for Assignment {}

#[derive(Debug)]
/// Block of statements
pub struct Block {
    pub statements: Vec<Statement>,
}
impl Expr for Block {}

#[derive(Debug)]
/// Single conditional statement.
pub struct Condition {
    pub condition: Expr,
    pub block: Block,
}
impl Expr for Condition {}

#[derive(Debug)]
/// Conditional block
pub struct Conditional {
    pub conditions: Vec<Condition>,
}
impl Expr for Conditional {}

#[derive(Debug)]
/// While loop struct.
pub struct WhileLoop {
    pub condition: Expr,
    pub block: Block,
}
impl Statement for WhileLoop {}

#[derive(Debug)]
/// For loop struct.
pub struct ForLoop {
    pub assignment: Assignment,
    pub source_var: Identifier,
    pub block: Block,
}
impl Statement for ForLoop {}

#[derive(Debug)]
/// Function defining struct.
pub struct FunctionDefinition {
    pub id: Identifier,
    pub function_type: Option<String>,
    pub args: Vec<Expr>,
    pub block: Block,
}
impl Statement for FunctionDefinition {}

#[derive(Debug)]
/// Class declaration struct.
pub struct ClassDeclaration {
    pub id: Identifier,
    pub block: Block,
}
impl Statement for ClassDeclaration {}

#[derive(Debug)]
/// Constant struct.
pub struct Constant {
    pub id: Identifier,
    pub val: Expr,
}
impl Statement for Constant {}

#[derive(Debug)]
/// Return statement struct.
pub struct Return {
    pub val: Expr
}
impl Statement for Return {}

#[derive(Debug)]
/// Module struct
/// Module does not implement `Statement` because
/// users should not be able to define modules in a file.
/// Each Wright file should be it's own independent Module.
pub struct Module {
    pub id: Identifier,
    pub content: Block,
}
<commit_msg>Fixed AST.rs<commit_after>/// Empty trait to define an expression superclass.
pub trait Expr {}

#[derive(Debug)]
/// Unary Operators
pub enum UnaryOperator {
    Not,
    Negative,
}
impl Expr for UnaryOperator {}

/// Empty trait to help define BinaryOperator as a superclass.
pub trait BinaryOperator {}

#[derive(Debug)]
/// Binary Operators
pub enum ArithmeticOperator {
    Add,
    Subtract,
    Multiply,
    Divide,
    Modulo,
    BitwiseAnd,
    BitwiseOr,
    BitwiseXor,
    LeftShift,
    RightShift,
    Increment,
    Decrement,
}
impl BinaryOperator for ArithmeticOperator {}

#[derive(Debug)]
/// Logical Operators
pub enum LogicalOperator {
    And,
    Or,
    Xor,
    ShortAnd,
    ShortOr,
}
impl BinaryOperator for LogicalOperator {}

#[derive(Debug)]
/// Relational Operators
pub enum RelationalOperators {
    Equal,
    NotEqual,
    GreaterThan,
    LessThan,
    GreaterOrEqual,
    LessOrEqual,
}
impl BinaryOperator for RelationalOperators {}

#[derive(Debug)]
/// Unary Expression.
pub struct UnaryExpr {
    pub operator: UnaryOperator,
    pub right: Box<Expr>,
}
impl Expr for UnaryExpr {}

#[derive(Debug)]
/// Binary Expression.
pub struct BinaryExpr{
    pub left: Box<Expr>,
    pub operator: Box<BinaryOperator>,
    pub right: Box<Expr>,
}
impl Expr for BinaryExpr {}

#[derive(Debug)]
/// Literal struct.
pub struct Literal {
    /// For type inference, when and where possible.
    pub literal_type: Option<String>,
    pub literal: String,
}
impl Expr for Literal {}

#[derive(Debug)]
/// Identifier struct.
pub struct Identifier {
    pub id: String,
}
impl Expr for Identifier {}

#[derive(Debug)]
/// Function call.
pub struct Call {
    pub callee: String,
    pub args: Vec<Box<Expr>>,
}
impl Expr for Call {}

/// Empty trait for statements.
pub trait Statement {}
/// All expressions can be converted to statements.
impl<T: Expr> Statement for T {}

#[derive(Debug)]
/// Different types of assignments, one for mutability, the other for immutability.
pub enum Assign {
    Let,
    Var,
}

#[derive(Debug)]
/// Assignment statement.
pub struct Assignment {
    pub left: Identifier,
    pub assign_type: Assign,
    pub right: Expr,
}
impl Statement for Assignment {}

#[derive(Debug)]
/// Block of statements
pub struct Block {
    pub statements: Vec<Box<Statement>>,
}
impl Expr for Block {}

#[derive(Debug)]
/// Single conditional statement.
pub struct Condition {
    pub condition: Box<Expr>,
    pub block: Block,
}
impl Expr for Condition {}

#[derive(Debug)]
/// Conditional block
pub struct Conditional {
    pub conditions: Vec<Condition>,
}
impl Expr for Conditional {}

#[derive(Debug)]
/// While loop struct.
pub struct WhileLoop {
    pub condition: Box<Expr>,
    pub block: Block,
}
impl Statement for WhileLoop {}

#[derive(Debug)]
/// For loop struct.
pub struct ForLoop {
    pub assignment: Box<Assignment>,
    pub source_var: Identifier,
    pub block: Block,
}
impl Statement for ForLoop {}

#[derive(Debug)]
/// Function defining struct.
pub struct FunctionDefinition {
    pub id: Identifier,
    pub function_type: Option<String>,
    pub args: Vec<Box<Expr>>,
    pub block: Block,
}
impl Statement for FunctionDefinition {}

#[derive(Debug)]
/// Class declaration struct.
pub struct ClassDeclaration {
    pub id: Identifier,
    pub block: Block,
}
impl Statement for ClassDeclaration {}

#[derive(Debug)]
/// Constant struct.
pub struct Constant {
    pub id: Identifier,
    pub val: Expr,
}
impl Statement for Constant {}

#[derive(Debug)]
/// Return statement struct.
pub struct Return {
    pub val: Expr
}
impl Statement for Return {}

#[derive(Debug)]
/// Module struct
/// Module does not implement `Statement` because
/// users should not be able to define modules in a file.
/// Each Wright file should be it's own independent Module.
pub struct Module {
    pub id: Identifier,
    pub content: Block,
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! CSS transitions and animations.

use clock_ticks;
use flow::{self, Flow};
use gfx::display_list::OpaqueNode;
use incremental::{self, RestyleDamage};
use layout_task::{LayoutTask, LayoutTaskData};
use msg::constellation_msg::{AnimationState, Msg, PipelineId};
use script::layout_interface::Animation;
use script_traits::ConstellationControlMsg;
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::sync::Arc;
use std::sync::mpsc::Sender;
use style::animation::{GetMod, PropertyAnimation};
use style::properties::ComputedValues;

/// Inserts transitions into the queue of running animations as applicable for the given style
/// difference. This is called from the layout worker threads.
pub fn start_transitions_if_applicable(new_animations_sender: &Sender<Animation>,
                                       node: OpaqueNode,
                                       old_style: &ComputedValues,
                                       new_style: &mut ComputedValues) {
    for i in 0..new_style.get_animation().transition_property.0.len() {
        // Create any property animations, if applicable.
        let property_animations = PropertyAnimation::from_transition(i, old_style, new_style);
        for property_animation in property_animations {
            // Set the property to the initial value.
            property_animation.update(new_style, 0.0);

            // Kick off the animation.
            let now = clock_ticks::precise_time_s();
            let animation_style = new_style.get_animation();
            let start_time =
                now + (animation_style.transition_delay.0.get_mod(i).seconds() as f64);
            new_animations_sender.send(Animation {
                node: node.id(),
                property_animation: property_animation,
                start_time: start_time,
                end_time: start_time +
                    (animation_style.transition_duration.0.get_mod(i).seconds() as f64),
            }).unwrap()
        }
    }
}

/// Processes any new animations that were discovered after style recalculation.
/// Also expire any old animations that have completed.
pub fn update_animation_state(rw_data: &mut LayoutTaskData, pipeline_id: PipelineId) {
    let mut new_running_animations = Vec::new();
    while let Ok(animation) = rw_data.new_animations_receiver.try_recv() {
        new_running_animations.push(animation)
    }

    let mut running_animations_hash = (*rw_data.running_animations).clone();

    // Expire old running animations.
    let now = clock_ticks::precise_time_s();
    let mut keys_to_remove = Vec::new();
    for (key, running_animations) in &mut running_animations_hash {
        running_animations.retain(|running_animation| {
            now < running_animation.end_time
        });
        if running_animations.len() == 0 {
            keys_to_remove.push(*key);
        }
    }
    for key in keys_to_remove {
        running_animations_hash.remove(&key).unwrap();
    }

    // Add new running animations.
    for new_running_animation in new_running_animations {
        match running_animations_hash.entry(OpaqueNode(new_running_animation.node)) {
            Entry::Vacant(entry) => {
                entry.insert(vec![new_running_animation]);
            }
            Entry::Occupied(mut entry) => entry.get_mut().push(new_running_animation),
        }
    }

    rw_data.running_animations = Arc::new(running_animations_hash);

    let animation_state;
    if rw_data.running_animations.is_empty() {
        animation_state = AnimationState::NoAnimationsPresent;
    } else {
        animation_state = AnimationState::AnimationsPresent;
    }

    rw_data.constellation_chan
           .0
           .send(Msg::ChangeRunningAnimationsState(pipeline_id, animation_state))
           .unwrap();

}

/// Recalculates style for a set of animations. This does *not* run with the DOM lock held.
pub fn recalc_style_for_animations(flow: &mut Flow,
                                   animations: &HashMap<OpaqueNode, Vec<Animation>>) {
    let mut damage = RestyleDamage::empty();
    flow.mutate_fragments(&mut |fragment| {
        if let Some(ref animations) = animations.get(&OpaqueNode(fragment.node.id())) {
            for animation in *animations {
                let now = clock_ticks::precise_time_s();
                let mut progress = (now - animation.start_time) / animation.duration();
                if progress > 1.0 {
                    progress = 1.0
                }
                if progress <= 0.0 {
                    continue
                }

                let mut new_style = fragment.style.clone();
                animation.property_animation.update(&mut *Arc::make_mut(&mut new_style),
                                                    progress);
                damage.insert(incremental::compute_damage(&Some(fragment.style.clone()),
                                                          &new_style));
                fragment.style = new_style
            }
        }
    });

    let base = flow::mut_base(flow);
    base.restyle_damage.insert(damage);
    for kid in base.children.iter_mut() {
        recalc_style_for_animations(kid, animations)
    }
}

/// Handles animation updates.
pub fn tick_all_animations(layout_task: &LayoutTask, rw_data: &mut LayoutTaskData) {
    layout_task.tick_animations(rw_data);

    layout_task.script_chan
               .send(ConstellationControlMsg::TickAllAnimations(layout_task.id))
               .unwrap();
}
<commit_msg>Auto merge of #8300 - pcwalton:avoid-animation-state-flooding, r=glennw<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! CSS transitions and animations.

use clock_ticks;
use flow::{self, Flow};
use gfx::display_list::OpaqueNode;
use incremental::{self, RestyleDamage};
use layout_task::{LayoutTask, LayoutTaskData};
use msg::constellation_msg::{AnimationState, Msg, PipelineId};
use script::layout_interface::Animation;
use script_traits::ConstellationControlMsg;
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::sync::Arc;
use std::sync::mpsc::Sender;
use style::animation::{GetMod, PropertyAnimation};
use style::properties::ComputedValues;

/// Inserts transitions into the queue of running animations as applicable for the given style
/// difference. This is called from the layout worker threads.
pub fn start_transitions_if_applicable(new_animations_sender: &Sender<Animation>,
                                       node: OpaqueNode,
                                       old_style: &ComputedValues,
                                       new_style: &mut ComputedValues) {
    for i in 0..new_style.get_animation().transition_property.0.len() {
        // Create any property animations, if applicable.
        let property_animations = PropertyAnimation::from_transition(i, old_style, new_style);
        for property_animation in property_animations {
            // Set the property to the initial value.
            property_animation.update(new_style, 0.0);

            // Kick off the animation.
            let now = clock_ticks::precise_time_s();
            let animation_style = new_style.get_animation();
            let start_time =
                now + (animation_style.transition_delay.0.get_mod(i).seconds() as f64);
            new_animations_sender.send(Animation {
                node: node.id(),
                property_animation: property_animation,
                start_time: start_time,
                end_time: start_time +
                    (animation_style.transition_duration.0.get_mod(i).seconds() as f64),
            }).unwrap()
        }
    }
}

/// Processes any new animations that were discovered after style recalculation.
/// Also expire any old animations that have completed.
pub fn update_animation_state(rw_data: &mut LayoutTaskData, pipeline_id: PipelineId) {
    let mut new_running_animations = Vec::new();
    while let Ok(animation) = rw_data.new_animations_receiver.try_recv() {
        new_running_animations.push(animation)
    }

    let mut running_animations_hash = (*rw_data.running_animations).clone();

    if running_animations_hash.is_empty() && new_running_animations.is_empty() {
        // Nothing to do. Return early so we don't flood the compositor with
        // `ChangeRunningAnimationsState` messages.
        return
    }

    // Expire old running animations.
    let now = clock_ticks::precise_time_s();
    let mut keys_to_remove = Vec::new();
    for (key, running_animations) in &mut running_animations_hash {
        running_animations.retain(|running_animation| {
            now < running_animation.end_time
        });
        if running_animations.len() == 0 {
            keys_to_remove.push(*key);
        }
    }
    for key in keys_to_remove {
        running_animations_hash.remove(&key).unwrap();
    }

    // Add new running animations.
    for new_running_animation in new_running_animations {
        match running_animations_hash.entry(OpaqueNode(new_running_animation.node)) {
            Entry::Vacant(entry) => {
                entry.insert(vec![new_running_animation]);
            }
            Entry::Occupied(mut entry) => entry.get_mut().push(new_running_animation),
        }
    }

    rw_data.running_animations = Arc::new(running_animations_hash);

    let animation_state;
    if rw_data.running_animations.is_empty() {
        animation_state = AnimationState::NoAnimationsPresent;
    } else {
        animation_state = AnimationState::AnimationsPresent;
    }

    rw_data.constellation_chan
           .0
           .send(Msg::ChangeRunningAnimationsState(pipeline_id, animation_state))
           .unwrap();

}

/// Recalculates style for a set of animations. This does *not* run with the DOM lock held.
pub fn recalc_style_for_animations(flow: &mut Flow,
                                   animations: &HashMap<OpaqueNode, Vec<Animation>>) {
    let mut damage = RestyleDamage::empty();
    flow.mutate_fragments(&mut |fragment| {
        if let Some(ref animations) = animations.get(&OpaqueNode(fragment.node.id())) {
            for animation in *animations {
                let now = clock_ticks::precise_time_s();
                let mut progress = (now - animation.start_time) / animation.duration();
                if progress > 1.0 {
                    progress = 1.0
                }
                if progress <= 0.0 {
                    continue
                }

                let mut new_style = fragment.style.clone();
                animation.property_animation.update(&mut *Arc::make_mut(&mut new_style),
                                                    progress);
                damage.insert(incremental::compute_damage(&Some(fragment.style.clone()),
                                                          &new_style));
                fragment.style = new_style
            }
        }
    });

    let base = flow::mut_base(flow);
    base.restyle_damage.insert(damage);
    for kid in base.children.iter_mut() {
        recalc_style_for_animations(kid, animations)
    }
}

/// Handles animation updates.
pub fn tick_all_animations(layout_task: &LayoutTask, rw_data: &mut LayoutTaskData) {
    layout_task.tick_animations(rw_data);

    layout_task.script_chan
               .send(ConstellationControlMsg::TickAllAnimations(layout_task.id))
               .unwrap();
}
<|endoftext|>


<commit_before>use learning::SupModel;
use linalg::matrix::Matrix;
use linalg::vector::Vector;
use learning::toolkit::activ_fn::ActivationFunc;
use learning::toolkit::activ_fn::Sigmoid;
use learning::toolkit::cost_fn::CostFunc;
use learning::toolkit::cost_fn::CrossEntropyError;
use learning::optim::grad_desc::GradientDesc;
use learning::optim::OptimAlgorithm;
use learning::optim::Optimizable;

/// Logistic Regression Model.
///
/// Contains option for optimized parameter.
pub struct LogisticRegressor {
    /// The parameters for the regression model.
    parameters: Option<Vector<f64>>,
    gd: GradientDesc,
}

impl Default for LogisticRegressor {
    fn default() -> LogisticRegressor {
        LogisticRegressor { parameters: None, gd: GradientDesc::default() }
    }
}
impl LogisticRegressor {
    /// Constructs untrained logistic regression model.
    ///
    /// # Examples
    ///
    /// ```
    /// use rusty_machine::learning::logistic_reg::LogisticRegressor;
    /// use rusty_machine::learning::optim::grad_desc::GradientDesc;
    ///
    /// let gd = GradientDesc::default();
    /// let mut logistic_mod = LogisticRegressor::new(gd);
    /// ```
    pub fn new(gd: GradientDesc) -> LogisticRegressor {
        LogisticRegressor { parameters: None, gd: gd }
    }

    /// Get the parameters from the model.
    ///
    /// Returns an option that is None if the model has not been trained.
    pub fn parameters(&self) -> Option<Vector<f64>> {
        match self.parameters {
            None => None,
            Some(ref x) => Some(x.clone()),
        }
    }
}

impl SupModel<Matrix<f64>, Vector<f64>> for LogisticRegressor {
    /// Train the logistic regression model.
    ///
    /// Takes training data and output values as input.
    ///
    /// # Examples
    ///
    /// ```
    /// use rusty_machine::learning::logistic_reg::LogisticRegressor;
    /// use rusty_machine::linalg::matrix::Matrix;
    /// use rusty_machine::linalg::vector::Vector;
    /// use rusty_machine::learning::SupModel;
    ///
    /// let mut logistic_mod = LogisticRegressor::default();
    /// let inputs = Matrix::new(3,2, vec![1.0, 2.0, 1.0, 3.0, 1.0, 4.0]);
    /// let targets = Vector::new(vec![5.0, 6.0, 7.0]);
    ///
    /// logistic_mod.train(&inputs, &targets);
    /// ```
    fn train(&mut self, inputs: &Matrix<f64>, targets: &Vector<f64>) {
        let initial_params = vec![0.5; inputs.cols()];

        let optimal_w = self.gd.optimize(self, &initial_params[..], inputs, targets);
        self.parameters = Some(Vector::new(optimal_w));
    }

    /// Predict output value from input data.
    ///
    /// Model must be trained before prediction can be made.
    fn predict(&self, inputs: &Matrix<f64>) -> Vector<f64> {
        match self.parameters {
            Some(ref v) => (inputs * v).apply(&Sigmoid::func),
            None => panic!("Model has not been trained."),
        }
    }
}

impl Optimizable for LogisticRegressor {
    type Inputs = Matrix<f64>;
    type Targets = Vector<f64>;

    fn compute_grad(&self, params: &[f64], inputs: &Matrix<f64>, targets: &Vector<f64>) -> (f64, Vec<f64>) {

        let beta_vec = Vector::new(params.to_vec());
        let outputs = (inputs * beta_vec).apply(&Sigmoid::func);

        let cost = CrossEntropyError::cost(&outputs, targets);
        let grad = (inputs.transpose() * (outputs-targets)) / (inputs.rows() as f64);

        println!("Cost is {0}", cost);

        (cost, grad.into_vec())
    }

}<commit_msg>Adding intercept terms to logistic regression<commit_after>use learning::SupModel;
use linalg::matrix::Matrix;
use linalg::vector::Vector;
use learning::toolkit::activ_fn::ActivationFunc;
use learning::toolkit::activ_fn::Sigmoid;
use learning::toolkit::cost_fn::CostFunc;
use learning::toolkit::cost_fn::CrossEntropyError;
use learning::optim::grad_desc::GradientDesc;
use learning::optim::OptimAlgorithm;
use learning::optim::Optimizable;

/// Logistic Regression Model.
///
/// Contains option for optimized parameter.
pub struct LogisticRegressor {
    /// The parameters for the regression model.
    parameters: Option<Vector<f64>>,
    gd: GradientDesc,
}

impl Default for LogisticRegressor {
    fn default() -> LogisticRegressor {
        LogisticRegressor { parameters: None, gd: GradientDesc::default() }
    }
}
impl LogisticRegressor {
    /// Constructs untrained logistic regression model.
    ///
    /// # Examples
    ///
    /// ```
    /// use rusty_machine::learning::logistic_reg::LogisticRegressor;
    /// use rusty_machine::learning::optim::grad_desc::GradientDesc;
    ///
    /// let gd = GradientDesc::default();
    /// let mut logistic_mod = LogisticRegressor::new(gd);
    /// ```
    pub fn new(gd: GradientDesc) -> LogisticRegressor {
        LogisticRegressor { parameters: None, gd: gd }
    }

    /// Get the parameters from the model.
    ///
    /// Returns an option that is None if the model has not been trained.
    pub fn parameters(&self) -> Option<Vector<f64>> {
        match self.parameters {
            None => None,
            Some(ref x) => Some(x.clone()),
        }
    }
}

impl SupModel<Matrix<f64>, Vector<f64>> for LogisticRegressor {
    /// Train the logistic regression model.
    ///
    /// Takes training data and output values as input.
    ///
    /// # Examples
    ///
    /// ```
    /// use rusty_machine::learning::logistic_reg::LogisticRegressor;
    /// use rusty_machine::linalg::matrix::Matrix;
    /// use rusty_machine::linalg::vector::Vector;
    /// use rusty_machine::learning::SupModel;
    ///
    /// let mut logistic_mod = LogisticRegressor::default();
    /// let inputs = Matrix::new(3,2, vec![1.0, 2.0, 1.0, 3.0, 1.0, 4.0]);
    /// let targets = Vector::new(vec![5.0, 6.0, 7.0]);
    ///
    /// logistic_mod.train(&inputs, &targets);
    /// ```
    fn train(&mut self, inputs: &Matrix<f64>, targets: &Vector<f64>) {
        let ones = Matrix::<f64>::ones(inputs.rows(), 1);
        let full_inputs = ones.hcat(inputs);

        let initial_params = vec![0.5; full_inputs.cols()];

        let optimal_w = self.gd.optimize(self, &initial_params[..], &full_inputs, targets);
        self.parameters = Some(Vector::new(optimal_w));
    }

    /// Predict output value from input data.
    ///
    /// Model must be trained before prediction can be made.
    fn predict(&self, inputs: &Matrix<f64>) -> Vector<f64> {
        if let Some(ref v) = self.parameters {
            let ones = Matrix::<f64>::ones(inputs.rows(), 1);
            let full_inputs = ones.hcat(inputs);
            (full_inputs * v).apply(&Sigmoid::func)
        }
        else {
            panic!("Model has not been trained.");
        }
    }
}

impl Optimizable for LogisticRegressor {
    type Inputs = Matrix<f64>;
    type Targets = Vector<f64>;

    fn compute_grad(&self, params: &[f64], inputs: &Matrix<f64>, targets: &Vector<f64>) -> (f64, Vec<f64>) {

        let beta_vec = Vector::new(params.to_vec());
        let outputs = (inputs * beta_vec).apply(&Sigmoid::func);

        let cost = CrossEntropyError::cost(&outputs, targets);
        let grad = (inputs.transpose() * (outputs-targets)) / (inputs.rows() as f64);

        println!("Cost is {0}", cost);

        (cost, grad.into_vec())
    }

}<|endoftext|>