<commit_before>mod statements;
mod expressions;

use std::io::Read;

use lexer::{Lexer};
use ast::*;
use compileerror::{Pos, CompileError};

use self::statements::*;

pub use self::expressions::{parse_function_call, parse_expression};

pub fn err<T: Sized>(pos: Pos, msg: String) -> Result<T, CompileError>
{
    Err(CompileError::new(pos, msg))
}

pub fn parse_program<Input: Read>(input: &mut Input) -> Result<Program, CompileError>
{
    let mut tq = try!(Lexer::new().read(input));
    let indent = try!(tq.expect_indent());
    let block = try!(parse_block(&mut tq, indent));
    Ok(Program::new(block))
}

#[cfg(test)]
use std::io::Cursor;

#[cfg(test)]
fn th_statement(data: &str) -> Statement
{
    let mut cursor = Cursor::new(data);
    let mut tq = Lexer::new().read(&mut cursor).expect("Lexing failed");
    let lvl = tq.expect_indent().expect("Missing indentation");
    parse_statement(&mut tq, lvl).expect("Parsing failed")
}

#[test]
fn test_simple_var()
{
    let stmt = th_statement("var x = 7");
    if let Statement::Variable(vars) = stmt
    {
        assert!(vars.len() == 1);
        let v = &vars[0];
        assert!(v.name == "x");
        assert!(v.typ.is_none());
        assert!(!v.is_const);
        if let Expression::Number(ref n) = v.init {
            assert!(n == "7");
        } else {
            assert!(false);
        }
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_simple_var_with_type()
{
    let stmt = th_statement("var x: int = 7");
    if let Statement::Variable(vars) = stmt
    {
        assert!(vars.len() == 1);
        let v = &vars[0];
        assert!(v.name == "x");
        assert!(v.typ == Some(Type::Primitive("int".into())));
        assert!(!v.is_const);
        if let Expression::Number(ref n) = v.init {
            assert!(n == "7");
        } else {
            assert!(false);
        }
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_simple_const()
{
    let stmt = th_statement("const x = 7");
    if let Statement::Variable(vars) = stmt
    {
        assert!(vars.len() == 1);
        let v = &vars[0];
        assert!(v.name == "x");
        assert!(v.typ.is_none());
        assert!(v.is_const);
        if let Expression::Number(ref n) = v.init {
            assert!(n == "7");
        } else {
            assert!(false);
        }
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_multiple_var()
{
    let stmt = th_statement("var x = 7, z = 888");

    if let Statement::Variable(vars) = stmt
    {
        assert!(vars.len() == 2);
        let v = &vars[0];
        assert!(v.name == "x");
        assert!(v.typ.is_none());
        assert!(!v.is_const);
        if let Expression::Number(ref n) = v.init {
            assert!(n == "7");
        } else {
            assert!(false);
        }

        let v = &vars[1];
        assert!(v.name == "z");
        assert!(v.typ.is_none());
        assert!(!v.is_const);
        if let Expression::Number(ref n) = v.init {
            assert!(n == "888");
        } else {
            assert!(false);
        }
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_multiple_var_with_indentation()
{
    let stmt = th_statement(r#"
var
    x = 7
    z = 888"#);
    if let Statement::Variable(vars) = stmt
    {
        assert!(vars.len() == 2);
        let v = &vars[0];
        assert!(v.name == "x");
        assert!(v.typ.is_none());
        assert!(!v.is_const);
        if let Expression::Number(ref n) = v.init {
            assert!(n == "7");
        } else {
            assert!(false);
        }

        let v = &vars[1];
        assert!(v.name == "z");
        assert!(v.typ.is_none());
        assert!(!v.is_const);
        if let Expression::Number(ref n) = v.init {
            assert!(n == "888");
        } else {
            assert!(false);
        }
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_while()
{
    let stmt = th_statement(r#"
while 1:
    print("true")
    print("something else")
    ""#);

    if let Statement::While(w) = stmt
    {
        assert!(w.cond == Expression::Number("1".into()));
        assert!(w.block.statements.len() == 2);

        let s = &w.block.statements[0];
        assert!(*s == Statement::Call(
            Call::new(
                "print".into(),
                vec![Expression::StringLiteral("true".into())]
            )));

        let s = &w.block.statements[1];
        assert!(*s == Statement::Call(
            Call::new(
                "print".into(),
                vec![Expression::StringLiteral("something else".into())]
            )));
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_while_single_line()
{
    let stmt = th_statement(r#"
while 1: print("true")
    ""#);

    if let Statement::While(w) = stmt
    {
        assert!(w.cond == Expression::Number("1".into()));
        assert!(w.block.statements.len() == 1);

        let s = &w.block.statements[0];
        assert!(*s == Statement::Call(
            Call::new(
                "print".into(),
                vec![Expression::StringLiteral("true".into())]
            )));
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_if()
{
    let stmt = th_statement(r#"
if 1:
    print("true")
    ""#);

    if let Statement::If(w) = stmt
    {
        assert!(w.cond == Expression::Number("1".into()));
        assert!(w.if_block.statements.len() == 1);
        assert!(w.else_block.is_none());

        let s = &w.if_block.statements[0];
        assert!(*s == Statement::Call(
            Call::new(
                "print".into(),
                vec![Expression::StringLiteral("true".into())]
            )));
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_if_else()
{
    let stmt = th_statement(r#"
if 1:
    print("true")
else:
    print("false")
    ""#);

    if let Statement::If(w) = stmt
    {
        assert!(w.cond == Expression::Number("1".into()));
        assert!(w.if_block.statements.len() == 1);
        assert!(w.else_block.is_some());

        let s = &w.if_block.statements[0];
        assert!(*s == Statement::Call(
            Call::new(
                "print".into(),
                vec![Expression::StringLiteral("true".into())]
            )));

        if let Some(eb) = w.else_block
        {
            assert!(eb.statements.len() == 1);
            let s = &eb.statements[0];
            assert!(*s == Statement::Call(
                Call::new(
                    "print".into(),
                    vec![Expression::StringLiteral("false".into())]
                )));
        }
        else
        {
            assert!(false);
        }
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_single_line_if()
{
    let stmt = th_statement(r#"
if 1: print("true")
    ""#);

    if let Statement::If(w) = stmt
    {
        assert!(w.cond == Expression::Number("1".into()));
        assert!(w.if_block.statements.len() == 1);
        assert!(w.else_block.is_none());

        let s = &w.if_block.statements[0];
        assert!(*s == Statement::Call(
            Call::new(
                "print".into(),
                vec![Expression::StringLiteral("true".into())]
            )));
    }
    else
    {
        assert!(false);
    }
}
<commit_msg>Add unittest for return statement parsing<commit_after>mod statements;
mod expressions;

use std::io::Read;

use lexer::{Lexer};
use ast::*;
use compileerror::{Pos, CompileError};

use self::statements::*;

pub use self::expressions::{parse_function_call, parse_expression};

pub fn err<T: Sized>(pos: Pos, msg: String) -> Result<T, CompileError>
{
    Err(CompileError::new(pos, msg))
}

pub fn parse_program<Input: Read>(input: &mut Input) -> Result<Program, CompileError>
{
    let mut tq = try!(Lexer::new().read(input));
    let indent = try!(tq.expect_indent());
    let block = try!(parse_block(&mut tq, indent));
    Ok(Program::new(block))
}

#[cfg(test)]
use std::io::Cursor;

#[cfg(test)]
fn th_statement(data: &str) -> Statement
{
    let mut cursor = Cursor::new(data);
    let mut tq = Lexer::new().read(&mut cursor).expect("Lexing failed");
    let lvl = tq.expect_indent().expect("Missing indentation");
    parse_statement(&mut tq, lvl).expect("Parsing failed")
}

#[test]
fn test_simple_var()
{
    let stmt = th_statement("var x = 7");
    if let Statement::Variable(vars) = stmt
    {
        assert!(vars.len() == 1);
        let v = &vars[0];
        assert!(v.name == "x");
        assert!(v.typ.is_none());
        assert!(!v.is_const);
        if let Expression::Number(ref n) = v.init {
            assert!(n == "7");
        } else {
            assert!(false);
        }
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_simple_var_with_type()
{
    let stmt = th_statement("var x: int = 7");
    if let Statement::Variable(vars) = stmt
    {
        assert!(vars.len() == 1);
        let v = &vars[0];
        assert!(v.name == "x");
        assert!(v.typ == Some(Type::Primitive("int".into())));
        assert!(!v.is_const);
        if let Expression::Number(ref n) = v.init {
            assert!(n == "7");
        } else {
            assert!(false);
        }
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_simple_const()
{
    let stmt = th_statement("const x = 7");
    if let Statement::Variable(vars) = stmt
    {
        assert!(vars.len() == 1);
        let v = &vars[0];
        assert!(v.name == "x");
        assert!(v.typ.is_none());
        assert!(v.is_const);
        if let Expression::Number(ref n) = v.init {
            assert!(n == "7");
        } else {
            assert!(false);
        }
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_multiple_var()
{
    let stmt = th_statement("var x = 7, z = 888");

    if let Statement::Variable(vars) = stmt
    {
        assert!(vars.len() == 2);
        let v = &vars[0];
        assert!(v.name == "x");
        assert!(v.typ.is_none());
        assert!(!v.is_const);
        if let Expression::Number(ref n) = v.init {
            assert!(n == "7");
        } else {
            assert!(false);
        }

        let v = &vars[1];
        assert!(v.name == "z");
        assert!(v.typ.is_none());
        assert!(!v.is_const);
        if let Expression::Number(ref n) = v.init {
            assert!(n == "888");
        } else {
            assert!(false);
        }
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_multiple_var_with_indentation()
{
    let stmt = th_statement(r#"
var
    x = 7
    z = 888"#);
    if let Statement::Variable(vars) = stmt
    {
        assert!(vars.len() == 2);
        let v = &vars[0];
        assert!(v.name == "x");
        assert!(v.typ.is_none());
        assert!(!v.is_const);
        if let Expression::Number(ref n) = v.init {
            assert!(n == "7");
        } else {
            assert!(false);
        }

        let v = &vars[1];
        assert!(v.name == "z");
        assert!(v.typ.is_none());
        assert!(!v.is_const);
        if let Expression::Number(ref n) = v.init {
            assert!(n == "888");
        } else {
            assert!(false);
        }
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_while()
{
    let stmt = th_statement(r#"
while 1:
    print("true")
    print("something else")
    ""#);

    if let Statement::While(w) = stmt
    {
        assert!(w.cond == Expression::Number("1".into()));
        assert!(w.block.statements.len() == 2);

        let s = &w.block.statements[0];
        assert!(*s == Statement::Call(
            Call::new(
                "print".into(),
                vec![Expression::StringLiteral("true".into())]
            )));

        let s = &w.block.statements[1];
        assert!(*s == Statement::Call(
            Call::new(
                "print".into(),
                vec![Expression::StringLiteral("something else".into())]
            )));
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_while_single_line()
{
    let stmt = th_statement(r#"
while 1: print("true")
    ""#);

    if let Statement::While(w) = stmt
    {
        assert!(w.cond == Expression::Number("1".into()));
        assert!(w.block.statements.len() == 1);

        let s = &w.block.statements[0];
        assert!(*s == Statement::Call(
            Call::new(
                "print".into(),
                vec![Expression::StringLiteral("true".into())]
            )));
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_if()
{
    let stmt = th_statement(r#"
if 1:
    print("true")
    ""#);

    if let Statement::If(w) = stmt
    {
        assert!(w.cond == Expression::Number("1".into()));
        assert!(w.if_block.statements.len() == 1);
        assert!(w.else_block.is_none());

        let s = &w.if_block.statements[0];
        assert!(*s == Statement::Call(
            Call::new(
                "print".into(),
                vec![Expression::StringLiteral("true".into())]
            )));
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_if_else()
{
    let stmt = th_statement(r#"
if 1:
    print("true")
else:
    print("false")
    ""#);

    if let Statement::If(w) = stmt
    {
        assert!(w.cond == Expression::Number("1".into()));
        assert!(w.if_block.statements.len() == 1);
        assert!(w.else_block.is_some());

        let s = &w.if_block.statements[0];
        assert!(*s == Statement::Call(
            Call::new(
                "print".into(),
                vec![Expression::StringLiteral("true".into())]
            )));

        if let Some(eb) = w.else_block
        {
            assert!(eb.statements.len() == 1);
            let s = &eb.statements[0];
            assert!(*s == Statement::Call(
                Call::new(
                    "print".into(),
                    vec![Expression::StringLiteral("false".into())]
                )));
        }
        else
        {
            assert!(false);
        }
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_single_line_if()
{
    let stmt = th_statement(r#"
if 1: print("true")
    ""#);

    if let Statement::If(w) = stmt
    {
        assert!(w.cond == Expression::Number("1".into()));
        assert!(w.if_block.statements.len() == 1);
        assert!(w.else_block.is_none());

        let s = &w.if_block.statements[0];
        assert!(*s == Statement::Call(
            Call::new(
                "print".into(),
                vec![Expression::StringLiteral("true".into())]
            )));
    }
    else
    {
        assert!(false);
    }
}

#[test]
fn test_return()
{
    let stmt = th_statement(r#"
return 5
    ""#);

    if let Statement::Return(w) = stmt
    {
        assert!(w.expr == Expression::Number("5".into()));
    }
    else
    {
        assert!(false);
    }
}
<|endoftext|>


<commit_before>use std::iter::Peekable;

use super::lexer::{Lexer, Token};

#[derive(Debug, PartialEq)]
pub enum Ast {
    TypeDefinition(String, Vec<Ast>),
    Parameter(String, String),
    Unexpected(Token),
    Empty,
}

type ParseResult = Result<Ast, Token>;

/// The parser in out language.
///
/// The parser transforms the input tokens into an AST.
pub struct Parser<'a> {
    tokens: Peekable<Lexer<'a>>,
}

impl Parser<'_> {
    /// Create a new parser.
    ///
    /// To build the parser, you need a [`Lexer`][0] with tokens. Then you can
    /// use the parser as a normal `Iterator`, wich iterates over [`Ast`s][1].
    ///
    /// # Examples
    ///
    ///     use simcom::lexer::{Lexer, Token};
    ///     use simcom::parser::{Ast, Parser};
    ///
    ///     let mut parser = Parser::new(Lexer::new("? Hello World"));
    ///     assert_eq!(parser.next().unwrap(), Ast::Unexpected(Token::Illegal));
    ///
    /// [0]: ../lexer/struct.Lexer.html
    /// [1]: enum.Ast.html
    pub fn new(tokens: Lexer) -> Parser {
        Parser { tokens: tokens.peekable() }
    }
}

impl Iterator for Parser<'_> {
    type Item = Ast;

    fn next(&mut self) -> Option<Self::Item> {
        match definition(&mut self.tokens) {
            Ok(ast) => Some(ast),
            Err(Token::EOF) => None,
            Err(token) => {
                advance_until_semicolon(&mut self.tokens);
                Some(Ast::Unexpected(token))
            },
        }
    }
}

/// Advances the iterator until a semicolon is found, consuming it.
/// Also, if we find a 'None' value, we stop because otherwise we will get stuck
/// in a never ending loop.
fn advance_until_semicolon(mut tokens: &mut Peekable<Lexer>) {
    match tokens.next() {
        None | Some(Token::Semicolon) => (),
        _ => advance_until_semicolon(&mut tokens),
    }
}

/// Matches an entire type definition. From Token::Type to Token::Semicolon.
/// Returns an Ast::TypeDefinition if everything went ok. Otherwise we get the
/// Token that was misplaced (thus unexpected).
///
/// TODO: Try to write this function a bit nicer.
fn definition(mut tokens: &mut Peekable<Lexer>) -> ParseResult {
    match tokens.next() {
        Some(Token::Type) => (),
        Some(t) => return Err(t),
        None => return Err(Token::EOF),
    }

    // Get the type's name from the first identifier.
    let name = match tokens.next() {
        Some(Token::Ident(name)) => name,
        Some(t) => return Err(t),
        None => return Err(Token::EOF),
    };

    match tokens.next() {
        Some(Token::ParL) => (),
        Some(t) => return Err(t),
        None => return Err(Token::EOF),
    }

    // Fill a parameter vector with the different vectors we find.
    let mut pars = Vec::new();
    if let Err(t) = parameters(&mut tokens, &mut pars) {
        return Err(t);
    }

    match tokens.next() {
        Some(Token::ParR) => (),
        Some(t) => return Err(t),
        None => return Err(Token::EOF),
    }

    match tokens.next() {
        Some(Token::Semicolon) => (),
        Some(t) => return Err(t),
        None => return Err(Token::EOF),
    }

    Ok(Ast::TypeDefinition(name, pars))
}

/// Matches a series of parameters, separated by a comma (Token::Comma).
///
/// Fills the passed 'res' vector. Return is Err(_) when an unexpected token was
/// found or when the 'tokens' iterator ends.
fn parameters(mut tokens: &mut Peekable<Lexer>,
    mut res: &mut Vec<Ast>) -> ParseResult {

    match parameter(tokens) {
        Ok(x) => res.push(x),
        Err(token) => return Err(token),
    }

    match tokens.peek() {
        Some(&Token::Comma) => {
            tokens.next(); // Consume Token::Comma.
            parameters(&mut tokens, &mut res)
        },
        _ => Ok(Ast::Empty)
    }
}

/// Matches a parameter (the ones inside the type definition's parenthesis).
/// Has the form (Token::Ident, Token::Colon, Token::Ident).
fn parameter(mut tokens: &mut Peekable<Lexer>) -> ParseResult {
    match tokens.next() {
        Some(Token::Ident(name)) => match tokens.next() {
            Some(Token::Colon) => match tokens.next() {
                Some(Token::Ident(tname)) => Ok(Ast::Parameter(name, tname)),
                None => Err(Token::EOF),
                Some(x) => Err(x),
            },
            None => Err(Token::EOF),
            Some(x) => Err(x),
        },
        None => Err(Token::EOF),
        Some(x) => Err(x),
    }
}

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

    fn get_parameter(input: &str) -> ParseResult {
        parameter(&mut Lexer::new(input).peekable())
    }

    fn get_parameters(input: &str) -> (ParseResult, Vec<Ast>) {
        let mut pars = Vec::new();
        let r = parameters(&mut Lexer::new(input).peekable(), &mut pars);

        (r, pars)
    }

    fn get_definition(input: &str) -> ParseResult {
        definition(&mut Lexer::new(input).peekable())
    }

    #[test]
    fn semicolon1() {
        let mut tokens = Lexer::new("Hola ,,();  )").peekable();
        advance_until_semicolon(&mut tokens);

        assert_eq!(tokens.next().unwrap(), Token::ParR);
    }

    #[test]
    fn semicolon2() {
        let mut tokens = Lexer::new(",,,,,,;;").peekable();
        advance_until_semicolon(&mut tokens);

        assert_eq!(tokens.next().unwrap(), Token::Semicolon);
    }

    #[test]
    fn semicolon3() {
        let mut tokens = Lexer::new("Hola ,,(); ").peekable();
        advance_until_semicolon(&mut tokens);

        assert_eq!(tokens.next(), None);
    }

    #[test]
    fn semicolon4() {
        let mut tokens = Lexer::new("Hey").peekable();
        advance_until_semicolon(&mut tokens);

        assert_eq!(tokens.next(), None);
    }

    #[test]
    fn good_definition() {
        let d = get_definition("tipo Punto(x: Punto);");

        assert_eq!(d.unwrap(), Ast::TypeDefinition(
            String::from("Punto"),
            vec![Ast::Parameter(
                String::from("x"),
                String::from("Punto"),
            )],
        ));
    }

    #[test]
    fn good_definition_many() {
        let d = get_definition("tipo Punto(x: Punto, x: P, x: P);");

        assert_eq!(d.unwrap(), Ast::TypeDefinition(
            String::from("Punto"),
            vec![
                Ast::Parameter(
                    String::from("x"),
                    String::from("Punto"),
                ),
                Ast::Parameter(
                    String::from("x"),
                    String::from("P"),
                ),
                Ast::Parameter(
                    String::from("x"),
                    String::from("P"),
                ),
            ],
        ));
    }

    #[test]
    fn missing_keyword() {
        let d = get_definition("tiipo Punto");
        assert_eq!(d.unwrap_err(), Token::Ident(String::from("tiipo")));
    }

    #[test]
    fn missing_identifier_definition() {
        let d = get_definition("tipo (,,,");
        assert_eq!(d.unwrap_err(), Token::ParL);
    }

    #[test]
    fn missing_parenthesis() {
        let d = get_definition("tipo x he");
        assert_eq!(d.unwrap_err(), Token::Ident(String::from("he")));

        let d = get_definition("tipo P(x: haha;");
        assert_eq!(d.unwrap_err(), Token::Semicolon);
    }

    #[test]
    fn missing_semicolon() {
        let d = get_definition("tipo P(x: E)");
        assert_eq!(d.unwrap_err(), Token::EOF);

        let d = get_definition("tipo P(x: E) \n tipo");
        assert_eq!(d.unwrap_err(), Token::Type);
    }

    #[test]
    fn error_propagation() {
        let d = get_definition("tipo Punto(x Punto);");
        assert_eq!(d.unwrap_err(), Token::Ident(String::from("Punto")));
    }

    #[test]
    fn good_parameter() {
        let p = get_parameter("name: Type");

        assert_eq!(p.unwrap(), Ast::Parameter(
            String::from("name"),
            String::from("Type"),
        ));
    }

    #[test]
    fn missing_colon() {
        let p = get_parameter("name Type");

        assert_eq!(p.unwrap_err(), Token::Ident(String::from("Type")));
    }

    #[test]
    fn missing_identifier() {
        let p = get_parameter("name: )");

        assert_eq!(p.unwrap_err(), Token::ParR);
    }

    #[test]
    fn good_parameters() {
        let (res, ps) = get_parameters("name: Type, other: othert");

        assert_eq!(res.unwrap(), Ast::Empty);
        assert_eq!(ps, vec![
            Ast::Parameter(
                String::from("name"),
                String::from("Type"),
            ),
            Ast::Parameter(
                String::from("other"),
                String::from("othert"),
            ),
        ]);
    }

    #[test]
    fn missing_comma() {
        let (res, ps) = get_parameters("name: Type other: othert");

        // Here the function doesn't report the next identifier token because
        // it ends if it doesn't find any Token::Comma's. The unexpected "other"
        // identifier will be reported by the ::definition function.
        assert_eq!(res.unwrap(), Ast::Empty);
        assert_eq!(ps, vec![
            Ast::Parameter(
                String::from("name"),
                String::from("Type"),
            ),
        ]);
    }

    #[test]
    fn missing_colon_parameters() {
        let (res, _) = get_parameters("name Type, other: othert");

        // Error propagates from ::parameter to ::parameters.
        assert_eq!(res.unwrap_err(), Token::Ident(String::from("Type")));
    }
}
<commit_msg>Remove unnecessary `mut` modifier.<commit_after>use std::iter::Peekable;

use super::lexer::{Lexer, Token};

#[derive(Debug, PartialEq)]
pub enum Ast {
    TypeDefinition(String, Vec<Ast>),
    Parameter(String, String),
    Unexpected(Token),
    Empty,
}

type ParseResult = Result<Ast, Token>;

/// The parser in out language.
///
/// The parser transforms the input tokens into an AST.
pub struct Parser<'a> {
    tokens: Peekable<Lexer<'a>>,
}

impl Parser<'_> {
    /// Create a new parser.
    ///
    /// To build the parser, you need a [`Lexer`][0] with tokens. Then you can
    /// use the parser as a normal `Iterator`, wich iterates over [`Ast`s][1].
    ///
    /// # Examples
    ///
    ///     use simcom::lexer::{Lexer, Token};
    ///     use simcom::parser::{Ast, Parser};
    ///
    ///     let mut parser = Parser::new(Lexer::new("? Hello World"));
    ///     assert_eq!(parser.next().unwrap(), Ast::Unexpected(Token::Illegal));
    ///
    /// [0]: ../lexer/struct.Lexer.html
    /// [1]: enum.Ast.html
    pub fn new(tokens: Lexer) -> Parser {
        Parser { tokens: tokens.peekable() }
    }
}

impl Iterator for Parser<'_> {
    type Item = Ast;

    fn next(&mut self) -> Option<Self::Item> {
        match definition(&mut self.tokens) {
            Ok(ast) => Some(ast),
            Err(Token::EOF) => None,
            Err(token) => {
                advance_until_semicolon(&mut self.tokens);
                Some(Ast::Unexpected(token))
            },
        }
    }
}

/// Advances the iterator until a semicolon is found, consuming it.
/// Also, if we find a 'None' value, we stop because otherwise we will get stuck
/// in a never ending loop.
fn advance_until_semicolon(mut tokens: &mut Peekable<Lexer>) {
    match tokens.next() {
        None | Some(Token::Semicolon) => (),
        _ => advance_until_semicolon(&mut tokens),
    }
}

/// Matches an entire type definition. From Token::Type to Token::Semicolon.
/// Returns an Ast::TypeDefinition if everything went ok. Otherwise we get the
/// Token that was misplaced (thus unexpected).
///
/// TODO: Try to write this function a bit nicer.
fn definition(mut tokens: &mut Peekable<Lexer>) -> ParseResult {
    match tokens.next() {
        Some(Token::Type) => (),
        Some(t) => return Err(t),
        None => return Err(Token::EOF),
    }

    // Get the type's name from the first identifier.
    let name = match tokens.next() {
        Some(Token::Ident(name)) => name,
        Some(t) => return Err(t),
        None => return Err(Token::EOF),
    };

    match tokens.next() {
        Some(Token::ParL) => (),
        Some(t) => return Err(t),
        None => return Err(Token::EOF),
    }

    // Fill a parameter vector with the different vectors we find.
    let mut pars = Vec::new();
    if let Err(t) = parameters(&mut tokens, &mut pars) {
        return Err(t);
    }

    match tokens.next() {
        Some(Token::ParR) => (),
        Some(t) => return Err(t),
        None => return Err(Token::EOF),
    }

    match tokens.next() {
        Some(Token::Semicolon) => (),
        Some(t) => return Err(t),
        None => return Err(Token::EOF),
    }

    Ok(Ast::TypeDefinition(name, pars))
}

/// Matches a series of parameters, separated by a comma (Token::Comma).
///
/// Fills the passed 'res' vector. Return is Err(_) when an unexpected token was
/// found or when the 'tokens' iterator ends.
fn parameters(mut tokens: &mut Peekable<Lexer>,
    mut res: &mut Vec<Ast>) -> ParseResult {

    match parameter(tokens) {
        Ok(x) => res.push(x),
        Err(token) => return Err(token),
    }

    match tokens.peek() {
        Some(&Token::Comma) => {
            tokens.next(); // Consume Token::Comma.
            parameters(&mut tokens, &mut res)
        },
        _ => Ok(Ast::Empty)
    }
}

/// Matches a parameter (the ones inside the type definition's parenthesis).
/// Has the form (Token::Ident, Token::Colon, Token::Ident).
fn parameter(tokens: &mut Peekable<Lexer>) -> ParseResult {
    match tokens.next() {
        Some(Token::Ident(name)) => match tokens.next() {
            Some(Token::Colon) => match tokens.next() {
                Some(Token::Ident(tname)) => Ok(Ast::Parameter(name, tname)),
                None => Err(Token::EOF),
                Some(x) => Err(x),
            },
            None => Err(Token::EOF),
            Some(x) => Err(x),
        },
        None => Err(Token::EOF),
        Some(x) => Err(x),
    }
}

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

    fn get_parameter(input: &str) -> ParseResult {
        parameter(&mut Lexer::new(input).peekable())
    }

    fn get_parameters(input: &str) -> (ParseResult, Vec<Ast>) {
        let mut pars = Vec::new();
        let r = parameters(&mut Lexer::new(input).peekable(), &mut pars);

        (r, pars)
    }

    fn get_definition(input: &str) -> ParseResult {
        definition(&mut Lexer::new(input).peekable())
    }

    #[test]
    fn semicolon1() {
        let mut tokens = Lexer::new("Hola ,,();  )").peekable();
        advance_until_semicolon(&mut tokens);

        assert_eq!(tokens.next().unwrap(), Token::ParR);
    }

    #[test]
    fn semicolon2() {
        let mut tokens = Lexer::new(",,,,,,;;").peekable();
        advance_until_semicolon(&mut tokens);

        assert_eq!(tokens.next().unwrap(), Token::Semicolon);
    }

    #[test]
    fn semicolon3() {
        let mut tokens = Lexer::new("Hola ,,(); ").peekable();
        advance_until_semicolon(&mut tokens);

        assert_eq!(tokens.next(), None);
    }

    #[test]
    fn semicolon4() {
        let mut tokens = Lexer::new("Hey").peekable();
        advance_until_semicolon(&mut tokens);

        assert_eq!(tokens.next(), None);
    }

    #[test]
    fn good_definition() {
        let d = get_definition("tipo Punto(x: Punto);");

        assert_eq!(d.unwrap(), Ast::TypeDefinition(
            String::from("Punto"),
            vec![Ast::Parameter(
                String::from("x"),
                String::from("Punto"),
            )],
        ));
    }

    #[test]
    fn good_definition_many() {
        let d = get_definition("tipo Punto(x: Punto, x: P, x: P);");

        assert_eq!(d.unwrap(), Ast::TypeDefinition(
            String::from("Punto"),
            vec![
                Ast::Parameter(
                    String::from("x"),
                    String::from("Punto"),
                ),
                Ast::Parameter(
                    String::from("x"),
                    String::from("P"),
                ),
                Ast::Parameter(
                    String::from("x"),
                    String::from("P"),
                ),
            ],
        ));
    }

    #[test]
    fn missing_keyword() {
        let d = get_definition("tiipo Punto");
        assert_eq!(d.unwrap_err(), Token::Ident(String::from("tiipo")));
    }

    #[test]
    fn missing_identifier_definition() {
        let d = get_definition("tipo (,,,");
        assert_eq!(d.unwrap_err(), Token::ParL);
    }

    #[test]
    fn missing_parenthesis() {
        let d = get_definition("tipo x he");
        assert_eq!(d.unwrap_err(), Token::Ident(String::from("he")));

        let d = get_definition("tipo P(x: haha;");
        assert_eq!(d.unwrap_err(), Token::Semicolon);
    }

    #[test]
    fn missing_semicolon() {
        let d = get_definition("tipo P(x: E)");
        assert_eq!(d.unwrap_err(), Token::EOF);

        let d = get_definition("tipo P(x: E) \n tipo");
        assert_eq!(d.unwrap_err(), Token::Type);
    }

    #[test]
    fn error_propagation() {
        let d = get_definition("tipo Punto(x Punto);");
        assert_eq!(d.unwrap_err(), Token::Ident(String::from("Punto")));
    }

    #[test]
    fn good_parameter() {
        let p = get_parameter("name: Type");

        assert_eq!(p.unwrap(), Ast::Parameter(
            String::from("name"),
            String::from("Type"),
        ));
    }

    #[test]
    fn missing_colon() {
        let p = get_parameter("name Type");

        assert_eq!(p.unwrap_err(), Token::Ident(String::from("Type")));
    }

    #[test]
    fn missing_identifier() {
        let p = get_parameter("name: )");

        assert_eq!(p.unwrap_err(), Token::ParR);
    }

    #[test]
    fn good_parameters() {
        let (res, ps) = get_parameters("name: Type, other: othert");

        assert_eq!(res.unwrap(), Ast::Empty);
        assert_eq!(ps, vec![
            Ast::Parameter(
                String::from("name"),
                String::from("Type"),
            ),
            Ast::Parameter(
                String::from("other"),
                String::from("othert"),
            ),
        ]);
    }

    #[test]
    fn missing_comma() {
        let (res, ps) = get_parameters("name: Type other: othert");

        // Here the function doesn't report the next identifier token because
        // it ends if it doesn't find any Token::Comma's. The unexpected "other"
        // identifier will be reported by the ::definition function.
        assert_eq!(res.unwrap(), Ast::Empty);
        assert_eq!(ps, vec![
            Ast::Parameter(
                String::from("name"),
                String::from("Type"),
            ),
        ]);
    }

    #[test]
    fn missing_colon_parameters() {
        let (res, _) = get_parameters("name Type, other: othert");

        // Error propagates from ::parameter to ::parameters.
        assert_eq!(res.unwrap_err(), Token::Ident(String::from("Type")));
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Drew Short <drew@sothr.com>.
//
// 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.

use std::iter::range_step_inclusive;

/**
    Determines if a specified number is prime.

    # Arguments

    * 'num' - The number to check for primality

    # Examples

    ```rust
    use sothr_lib::prime_util::is_prime;
    assert_eq!(true, is_prime(1));
    assert_eq!(true, is_prime(5));
    assert_eq!(false, is_prime(6));
    assert_eq!(true, is_prime(6857));
    assert_eq!(false, is_prime(75031));
    ```
*/
pub fn is_prime(num: u64) -> bool {
    // 1-3 are prime numbers
    if num <= 3 {
        return true;
    }

    // numbers divisible by 2 and 3, but greater than 3 are not prime
    if num % 2 == 0 || num % 3 == 0 {
        return false;
    }

    // Check every number between i=5 and the square of i than is less than the
    // desired number
    let mut i = 5;
    while i*i < num {
    	// If the number is evenly divisible by i or i+2 it is not prime
        if num % i == 0 || num % (i+2) == 0 {
            return false;
        }
        // Increment by 6 because it is the product of 2 and 3. Therefore of
        // the numbers between 5 and 11 (i and i+6) only 5 and 7 could be prime
        // values. 6, 8, 9 and 10 are products or sums of 2 and 3.
        i += 6;
    }
    // If this far, then the number is definitively prime
    true
}

/**
  Generate a list of primes between 0 and the end value.

  # Arguments

  * 'look_until' - The end of the range to look for primes within

  # Examples

  ```rust
  use sothr_lib::prime_util::list_of_primes;
  let prime_list = vec![2,3,5,7,11];
  assert_eq!(prime_list, list_of_primes(12).expect("No Primes?!?!?"));
  ```
*/
pub fn list_of_primes(look_until: u64) -> Option<Vec<u64>> {
  if look_until < 2u64 {
    return None
  }

  let end = look_until as usize;

  //prepopulate the sieve
  let mut sieve: Vec<bool> = Vec::with_capacity(end/2);
  let mut i: usize = 0;
  while i < end {
    sieve.push(true);
    i += 1;
  }

  let f_look_until = look_until as f64;
  let estimate_of_primes = ((f_look_until / f_look_until.ln()) * (1f64 + (1.2762 / f_look_until.ln()))) as usize;
  let mut primes: Vec<u64> = Vec::with_capacity(estimate_of_primes);
  primes.push(2u64);

  let limit = (((look_until/2) as f64).sqrt() as usize) + 1;

  // in this lineup index 0 == 3
  // therefore index 1 == 5, 2 == 7, 3 == 9, etc...
  for i in 0..end/2 {
    if sieve[i] {
      primes.push((i+i+3) as u64);
      if i < limit {
        // selectively sieve out non primes. We're only concerned with odds as
        // we've already removed even values from the list.
        // i = 0, therefore i represents 3
        // i+i+3 = 3
        // simple proofs of odd counts
        // 0 1 2 3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
        //[3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49]
        //0,3,6,9,12 = <3>,9,15,21,27
        //1,6,11,16 = <5>,15,25,35
        //2,9,16,23 = <7>,21,35,49
        for j in range_step_inclusive(i+i+3, end-1, i+i+3) {
          sieve[j] = false;
        }
      }
    }
  }
  Some(primes)
}

/**
    Find a specified number of primes.

    # Arguments

    * 'look_until' - The end of the range to look for primes within

    # Examples

    ```rust
    use sothr_lib::prime_util::find_number_of_primes;
    let prime_list = vec![2,3,5,7,11];
    assert_eq!(prime_list, find_number_of_primes(5).expect("No Primes?!?!?"));
    ```
*/
pub fn find_number_of_primes(num_of_primes: usize) -> Option<Vec<u64>> {
    // very slow way to find primes
    // TODO: Use a more efficient algorithm in the future

    if num_of_primes == 0 {
        return None;
    }

    let mut primes: Vec<u64> = Vec::with_capacity(num_of_primes);
    primes.push(2u64);

    let mut num = 3u64;
    loop {
        let mut is_prime = true;
        for prime in primes.iter() {
            if num % prime == 0 {
                is_prime = false;
                break;
            }
        }
        if is_prime { primes.push(num); }
        if primes.len() >= num_of_primes { break; }
        num += 1;
    }

    Some(primes)
}
<commit_msg>Fix to the prime finder. Was previously finding more primes than required. Will need to revisit algorithm to address the issue more elegantly.<commit_after>// Copyright 2015 Drew Short <drew@sothr.com>.
//
// 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.

use std::iter::range_step_inclusive;

/**
    Determines if a specified number is prime.

    # Arguments

    * 'num' - The number to check for primality

    # Examples

    ```rust
    use sothr_lib::prime_util::is_prime;
    assert_eq!(true, is_prime(1));
    assert_eq!(true, is_prime(5));
    assert_eq!(false, is_prime(6));
    assert_eq!(true, is_prime(6857));
    assert_eq!(false, is_prime(75031));
    ```
*/
pub fn is_prime(num: u64) -> bool {
    // 1-3 are prime numbers
    if num <= 3 {
        return true;
    }

    // numbers divisible by 2 and 3, but greater than 3 are not prime
    if num % 2 == 0 || num % 3 == 0 {
        return false;
    }

    // Check every number between i=5 and the square of i than is less than the
    // desired number
    let mut i = 5;
    while i*i < num {
    	// If the number is evenly divisible by i or i+2 it is not prime
        if num % i == 0 || num % (i+2) == 0 {
            return false;
        }
        // Increment by 6 because it is the product of 2 and 3. Therefore of
        // the numbers between 5 and 11 (i and i+6) only 5 and 7 could be prime
        // values. 6, 8, 9 and 10 are products or sums of 2 and 3.
        i += 6;
    }
    // If this far, then the number is definitively prime
    true
}

/**
  Generate a list of primes between 0 and the end value.

  # Arguments

  * 'look_until' - The end of the range to look for primes within

  # Examples

  ```rust
  use sothr_lib::prime_util::list_of_primes;
  let prime_list = vec![2,3,5,7];
  assert_eq!(prime_list, list_of_primes(10).expect("No Primes?!?!?"));
  ```
*/
pub fn list_of_primes(look_until: u64) -> Option<Vec<u64>> {
  if look_until < 2u64 {
    return None
  }

  let end = look_until as usize;

  //prepopulate the sieve
  let mut sieve: Vec<bool> = Vec::with_capacity(end/2);
  let mut i: usize = 0;
  while i < end {
    sieve.push(true);
    i += 1;
  }

  let f_look_until = look_until as f64;
  let estimate_of_primes = ((f_look_until / f_look_until.ln()) * (1f64 + (1.2762 / f_look_until.ln()))) as usize;
  let mut primes: Vec<u64> = Vec::with_capacity(estimate_of_primes);
  primes.push(2u64);

  let limit = (((look_until/2) as f64).sqrt() as usize) + 1;

  // in this lineup index 0 == 3
  // therefore index 1 == 5, 2 == 7, 3 == 9, etc...
  for i in 0..end/2 {
    if sieve[i] {
      primes.push((i+i+3) as u64);
      if i < limit {
        // selectively sieve out non primes. We're only concerned with odds as
        // we've already removed even values from the list.
        // i = 0, therefore i represents 3
        // i+i+3 = 3
        // simple proofs of odd counts
        // 0 1 2 3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
        //[3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49]
        //0,3,6,9,12 = <3>,9,15,21,27
        //1,6,11,16 = <5>,15,25,35
        //2,9,16,23 = <7>,21,35,49
        for j in range_step_inclusive(i+i+3, end-1, i+i+3) {
          sieve[j] = false;
        }
      }
    }
  }
  // Fix for primes over the limit
  for i in (0..primes.len()).rev() {
    if primes[i] >= look_until {
        primes.pop();
        continue;
    }
    break;
  }
  Some(primes)
}

/**
    Find a specified number of primes.

    # Arguments

    * 'look_until' - The end of the range to look for primes within

    # Examples

    ```rust
    use sothr_lib::prime_util::find_number_of_primes;
    let prime_list = vec![2,3,5,7,11];
    assert_eq!(prime_list, find_number_of_primes(5).expect("No Primes?!?!?"));
    ```
*/
pub fn find_number_of_primes(num_of_primes: usize) -> Option<Vec<u64>> {
    // very slow way to find primes
    // TODO: Use a more efficient algorithm in the future

    if num_of_primes == 0 {
        return None;
    }

    let mut primes: Vec<u64> = Vec::with_capacity(num_of_primes);
    primes.push(2u64);

    let mut num = 3u64;
    loop {
        let mut is_prime = true;
        for prime in primes.iter() {
            if num % prime == 0 {
                is_prime = false;
                break;
            }
        }
        if is_prime { primes.push(num); }
        if primes.len() >= num_of_primes { break; }
        num += 1;
    }

    Some(primes)
}
<|endoftext|>


<commit_before>use std::sync::{Condvar, Mutex, Arc};
use std::sync::atomic::{AtomicUsize, Ordering};

use std::ops::Drop;

use std::option::Option;

use std::fmt::{Debug, Formatter, Result};

struct LatchInner {
    mutex: Mutex<()>,
    counts: AtomicUsize,
    condition: Condvar
}

impl LatchInner {

    fn new(counts: usize) -> LatchInner {
        LatchInner {
            mutex: Mutex::new(()),
            counts: AtomicUsize::new(counts),
            condition: Condvar::new()
        }
    }

    fn await(&self) {
        let mut guard = self.mutex.lock().unwrap();
        while self.get_counts() > 0 {
            guard = self.condition.wait(guard).unwrap();
        }
    }

    fn count_down(&self) {
        let guard = self.mutex.lock().unwrap();
        let count = self.counts.fetch_sub(1, Ordering::Relaxed);
        if count == 1 {
            self.condition.notify_all();
        }
        drop(guard);
    }

    fn get_counts(&self) -> usize {
        self.counts.load(Ordering::Relaxed)
    }
}

/// A synchronization aid that allows one or more threads to wait until a set
/// of operations being performed in other threads completes.
/// A CountDownLatch is initialized with a given count. The await methods block
/// until the current count reaches zero due to invocations of the count_down()
/// method, after which all waiting threads are released and any subsequent
/// invocations of await return immediately. This is a one-shot phenomenon --
/// the count cannot be reset.
#[derive(Clone)]
pub struct CountDownLatch {
    inner: Arc<LatchInner>
}

impl CountDownLatch {

    /// Create new CountDownLatch with specified counts
    pub fn new(counts: usize) -> CountDownLatch {
        CountDownLatch {
            inner: Arc::new(LatchInner::new(counts))
        }
    }

    /// Block thread until number of counts is zero
    pub fn await(&self) {
        self.inner.await();
    }

    /// Decrease number of counts on '1'
    pub fn count_down(&self) {
        self.inner.count_down();
    }

    /// Get current number of counts
    pub fn get_counts(&self) -> usize {
        self.inner.get_counts()
    }
}

/// An RAII guard which will release a resource acquired from a semaphore
/// when dropped.
pub struct SemaphoreGuard<'owner> {
    owner: &'owner SemaphoreInner
}

impl <'owner> SemaphoreGuard<'owner> {

    fn new(inner: &'owner SemaphoreInner) -> SemaphoreGuard<'owner> {
        SemaphoreGuard { owner: inner }
    }
}

impl <'owner> Drop for SemaphoreGuard<'owner> {

    fn drop(&mut self) {
        self.owner.release();
    }
}

impl <'owner> Debug for SemaphoreGuard<'owner> {

    fn fmt(&self, fmt: &mut Formatter) -> Result {
        write!(fmt, "[Semaphore Guard]")
    }
}

struct SemaphoreInner {
    mutex: Mutex<()>,
    permissions: AtomicUsize,
    max_permissions: usize,
    condition: Condvar
}

impl SemaphoreInner {

    fn new(permissions: usize) -> SemaphoreInner {
        SemaphoreInner {
            mutex: Mutex::new(()),
            permissions: AtomicUsize::new(permissions),
            max_permissions: permissions,
            condition: Condvar::new()
        }
    }

    fn acquire(&self) -> SemaphoreGuard {
        let mut guard = self.mutex.lock().unwrap();
        while self.get_permissions_number() < 1 {
            guard = self.condition.wait(guard).unwrap();
        }
        self.decrease_permission();
        SemaphoreGuard::new(self)
    }

    fn try_acquire(&self) -> Option<SemaphoreGuard> {
        let try_guard = self.mutex.try_lock();
        match try_guard {
            Ok(_) => {
                if self.get_permissions_number() > 0 {
                    self.decrease_permission();
                    Some(SemaphoreGuard::new(self))
                } else {
                    None
                }
            },
            Err(_) => None,
        }
    }

    fn release(&self) {
        let guard = self.mutex.lock().unwrap();
        if self.get_permissions_number() < self.max_permissions {
            self.increase_permission();
            self.condition.notify_all();
        }
        drop(guard);
    }

    fn get_permissions_number(&self) -> usize {
        self.permissions.load(Ordering::Relaxed)
    }

    fn decrease_permission(&self) {
        self.permissions.fetch_sub(1, Ordering::Relaxed);
    }

    fn increase_permission(&self) {
        self.permissions.fetch_add(1, Ordering::Relaxed);
    }
}

/// A counting, blocking, semaphore.
/// Semaphores are a form of atomic counter where access is only granted
/// if the counter is a positive value. Each acquisition will block the calling
/// thread until the counter is positive, and each release will increment the
/// counter and unblock any threads if necessary.
/// Semaphores are often used to restrict the number of threads than can access
/// some (physical or logical) resource. For example, here is a class that uses
/// a semaphore to control access to a pool of items:
#[derive(Clone)]
pub struct Semaphore {
    inner: Arc<SemaphoreInner>
}

impl Semaphore {

    /// Create new Semaphore with specified number of permissions
    pub fn new(permissions: usize) -> Semaphore {
        Semaphore {
            inner: Arc::new(SemaphoreInner::new(permissions))
        }
    }

    /// Acquire permission from Semaphore
    /// Block current thread if no permission left
    pub fn acquire(&self) -> SemaphoreGuard {
        self.inner.acquire()
    }

    /// Try acquire permission
    /// Does not block thread
    pub fn try_acquire(&self) -> Option<SemaphoreGuard> {
        self.inner.try_acquire()
    }

    /// Release Semaphore permission
    /// Notify all threads that wait for permission
    /// @see Semaphore::acquire
    pub fn release(&self) {
        self.inner.release()
    }
}
<commit_msg>count down letch refactoring<commit_after>use std::sync::{Condvar, Mutex, Arc};
use std::sync::atomic::{AtomicUsize, Ordering};

use std::ops::Drop;

use std::option::Option;

use std::fmt::{Debug, Formatter, Result};

struct LatchInner {
    mutex: Mutex<()>,
    counts: AtomicUsize,
    condition: Condvar
}

impl LatchInner {

    fn new(counts: usize) -> LatchInner {
        LatchInner {
            mutex: Mutex::new(()),
            counts: AtomicUsize::new(counts),
            condition: Condvar::new()
        }
    }

    fn await(&self) {
        let mut guard = self.mutex.lock().unwrap();
        while self.get_counts() > 0 {
            guard = self.condition.wait(guard).unwrap();
        }
    }

    fn count_down(&self) {
        let guard = self.mutex.lock().unwrap();
        self.counts.fetch_sub(1, Ordering::Relaxed);
        if self.get_counts() == 0 {
            self.condition.notify_all();
        }
        drop(guard);
    }

    fn get_counts(&self) -> usize {
        self.counts.load(Ordering::Relaxed)
    }
}

/// A synchronization aid that allows one or more threads to wait until a set
/// of operations being performed in other threads completes.
/// A CountDownLatch is initialized with a given count. The await methods block
/// until the current count reaches zero due to invocations of the count_down()
/// method, after which all waiting threads are released and any subsequent
/// invocations of await return immediately. This is a one-shot phenomenon --
/// the count cannot be reset.
#[derive(Clone)]
pub struct CountDownLatch {
    inner: Arc<LatchInner>
}

impl CountDownLatch {

    /// Create new CountDownLatch with specified counts
    pub fn new(counts: usize) -> CountDownLatch {
        CountDownLatch {
            inner: Arc::new(LatchInner::new(counts))
        }
    }

    /// Block thread until number of counts is zero
    pub fn await(&self) {
        self.inner.await();
    }

    /// Decrease number of counts on '1'
    pub fn count_down(&self) {
        self.inner.count_down();
    }

    /// Get current number of counts
    pub fn get_counts(&self) -> usize {
        self.inner.get_counts()
    }
}

/// An RAII guard which will release a resource acquired from a semaphore
/// when dropped.
pub struct SemaphoreGuard<'owner> {
    owner: &'owner SemaphoreInner
}

impl <'owner> SemaphoreGuard<'owner> {

    fn new(inner: &'owner SemaphoreInner) -> SemaphoreGuard<'owner> {
        SemaphoreGuard { owner: inner }
    }
}

impl <'owner> Drop for SemaphoreGuard<'owner> {

    fn drop(&mut self) {
        self.owner.release();
    }
}

impl <'owner> Debug for SemaphoreGuard<'owner> {

    fn fmt(&self, fmt: &mut Formatter) -> Result {
        write!(fmt, "[Semaphore Guard]")
    }
}

struct SemaphoreInner {
    mutex: Mutex<()>,
    permissions: AtomicUsize,
    max_permissions: usize,
    condition: Condvar
}

impl SemaphoreInner {

    fn new(permissions: usize) -> SemaphoreInner {
        SemaphoreInner {
            mutex: Mutex::new(()),
            permissions: AtomicUsize::new(permissions),
            max_permissions: permissions,
            condition: Condvar::new()
        }
    }

    fn acquire(&self) -> SemaphoreGuard {
        let mut guard = self.mutex.lock().unwrap();
        while self.get_permissions_number() < 1 {
            guard = self.condition.wait(guard).unwrap();
        }
        self.decrease_permission();
        SemaphoreGuard::new(self)
    }

    fn try_acquire(&self) -> Option<SemaphoreGuard> {
        let try_guard = self.mutex.try_lock();
        match try_guard {
            Ok(_) => {
                if self.get_permissions_number() > 0 {
                    self.decrease_permission();
                    Some(SemaphoreGuard::new(self))
                } else {
                    None
                }
            },
            Err(_) => None,
        }
    }

    fn release(&self) {
        let guard = self.mutex.lock().unwrap();
        if self.get_permissions_number() < self.max_permissions {
            self.increase_permission();
            self.condition.notify_all();
        }
        drop(guard);
    }

    fn get_permissions_number(&self) -> usize {
        self.permissions.load(Ordering::Relaxed)
    }

    fn decrease_permission(&self) {
        self.permissions.fetch_sub(1, Ordering::Relaxed);
    }

    fn increase_permission(&self) {
        self.permissions.fetch_add(1, Ordering::Relaxed);
    }
}

/// A counting, blocking, semaphore.
/// Semaphores are a form of atomic counter where access is only granted
/// if the counter is a positive value. Each acquisition will block the calling
/// thread until the counter is positive, and each release will increment the
/// counter and unblock any threads if necessary.
/// Semaphores are often used to restrict the number of threads than can access
/// some (physical or logical) resource. For example, here is a class that uses
/// a semaphore to control access to a pool of items:
#[derive(Clone)]
pub struct Semaphore {
    inner: Arc<SemaphoreInner>
}

impl Semaphore {

    /// Create new Semaphore with specified number of permissions
    pub fn new(permissions: usize) -> Semaphore {
        Semaphore {
            inner: Arc::new(SemaphoreInner::new(permissions))
        }
    }

    /// Acquire permission from Semaphore
    /// Block current thread if no permission left
    pub fn acquire(&self) -> SemaphoreGuard {
        self.inner.acquire()
    }

    /// Try acquire permission
    /// Does not block thread
    pub fn try_acquire(&self) -> Option<SemaphoreGuard> {
        self.inner.try_acquire()
    }

    /// Release Semaphore permission
    /// Notify all threads that wait for permission
    /// @see Semaphore::acquire
    pub fn release(&self) {
        self.inner.release()
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::borrow::Cow;
use std::error::Error as StdError;

///Struct which represents the positions in the source file
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct SourcePosition {
    ///Current line of the input
    pub line: i32,
    ///Current column of the input
    pub column: i32
}
impl SourcePosition {
    fn start() -> SourcePosition {
        SourcePosition { line: 1, column: 1 }
    }

    fn update(&mut self, c: &char) {
        self.column += 1;
        if *c == '\n' {
            self.column = 1;
            self.line += 1;
        }
    }
}

///Enum used to store information about an error that has occured
#[derive(Debug)]
pub enum Error {
    ///Error indicating an unexpected token has been encountered in the stream
    Unexpected(char),
    ///Error indicating that the parser expected something else
    Expected(Cow<'static, str>),
    ///Generic message
    Message(Cow<'static, str>),
    ///Variant for containing other types of errors
    Other(Box<StdError>)
}

impl PartialEq for Error {
    fn eq(&self, other: &Error) -> bool {
        match (self, other) {
            (&Error::Unexpected(l), &Error::Unexpected(r)) => l == r,
            (&Error::Expected(ref l), &Error::Expected(ref r)) => l == r,
            (&Error::Message(ref l), &Error::Message(ref r)) => l == r,
            _ => false
        }
    }
}

impl <E> From<E> for Error where E: StdError + 'static {
    fn from(e: E) -> Error {
        Error::Other(Box::new(e))
    }
}

///Enum used to indicate if a parser consumed any items of the stream it was given as an input
#[derive(Clone, PartialEq, Debug, Copy)]
pub enum Consumed<T> {
    ///Constructor indicating that the parser has consumed elements
    Consumed(T),
    ///Constructor indicating that the parser did not consume any elements
    Empty(T)
}

impl <T> Consumed<T> {

    ///Returns true if `self` is empty
    pub fn is_empty(&self) -> bool {
        match *self {
            Consumed::Empty(_) => true,
            Consumed::Consumed(_) => false
        }
    }

    ///Extracts the contained value
    pub fn into_inner(self) -> T {
        match self {
            Consumed::Empty(x) => x,
            Consumed::Consumed(x) => x
        }
    }

    ///Converts `self` into the Consumed state
    pub fn as_consumed(self) -> Consumed<T> {
        Consumed::Consumed(self.into_inner())
    }

    ///Converts `self` into theEmpty state
    pub fn as_empty(self) -> Consumed<T> {
        Consumed::Empty(self.into_inner())
    }

    ///Maps over the contained value without changing the consumed state
    pub fn map<F, U>(self, f: F) -> Consumed<U>
        where F: FnOnce(T) -> U {
        match self {
            Consumed::Empty(x) => Consumed::Empty(f(x)),
            Consumed::Consumed(x) => Consumed::Consumed(f(x))
        }
    }

    ///Combines the Consumed flags from `self` and the result of `f`
    ///
    ///```
    /// # extern crate parser_combinators as pc;
    /// # use pc::*;
    /// # use pc::primitives::State;
    /// # fn main() {
    /// //Parses a characther of string literal and handles the escaped characthers \\ and \" as \
    /// //and " respectively
    /// fn char(input: State<&str>) -> ParseResult<char, &str> {
    ///     let (c, input) = try!(satisfy(|c| c != '"').parse_state(input));
    ///     match c {
    ///         //Since the `char` parser has already consumed some of the input `combine` is used
    ///         //propagate the consumed state to the next part of the parser
    ///         '\\' => input.combine(|input| {
    ///             satisfy(|c| c == '"' || c == '\\')
    ///                 .map(|c| {
    ///                     match c {
    ///                         '"' => '"',
    ///                         '\\' => '\\',
    ///                         c => c
    ///                     }
    ///                 })
    ///                 .parse_state(input)
    ///             }),
    ///         _ => Ok((c, input))
    ///     }
    /// }
    /// let result = many(parser(char))
    ///     .parse(r#"abc\"\\"#);
    /// assert_eq!(result, Ok((r#"abc"\"#.to_string(), "")));
    /// }
    ///```
    pub fn combine<F, U, I>(self, f: F) -> ParseResult<U, I>
        where F: FnOnce(T) -> ParseResult<U, I> {
        match self {
            Consumed::Consumed(x) => {
                match f(x) {
                    Ok((v, Consumed::Empty(rest))) => Ok((v, Consumed::Consumed(rest))),
                    Err(Consumed::Empty(err)) => Err(Consumed::Consumed(err)),
                    y => y
                }
            }
            Consumed::Empty(x) => f(x)
        }
    }
}
///Struct which hold information about an error that occured at a specific position.
///Can hold multiple instances of `Error` if more that one error occured at the position.
#[derive(Debug, PartialEq)]
pub struct ParseError {
    ///The position where the error occured
    pub position: SourcePosition,
    ///A vector containing specific information on what errors occured at `position`
    pub errors: Vec<Error>
}

impl ParseError {
    pub fn new(position: SourcePosition, error: Error) -> ParseError {
        ParseError { position: position, errors: vec![error] }
    }
    pub fn add_message<S>(&mut self, message: S)
        where S: Into<Cow<'static, str>> {
        self.add_error(Error::Message(message.into()));
    }
    pub fn add_error(&mut self, message: Error) {
        //Don't add duplicate errors
        if self.errors.iter().find(|msg| **msg == message).is_none() {
            self.errors.push(message);
        }
    }
    pub fn set_expected(&mut self, message: Cow<'static, str>) {
        //Remove all other expected messages
        self.errors.retain(|e| match *e { Error::Expected(_) => false, _ => true });
        self.errors.push(Error::Expected(message));
    }
    pub fn merge(mut self, other: ParseError) -> ParseError {
        use std::cmp::Ordering;
        //Only keep the errors which occured after consuming the most amount of data
        match self.position.cmp(&other.position) {
            Ordering::Less => other,
            Ordering::Greater => self,
            Ordering::Equal => {
                for message in other.errors.into_iter() {
                    self.add_error(message);
                }
                self
            }
        }
    }
}

impl StdError for ParseError {
    fn description(&self) -> &str { "parse error" }
}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(writeln!(f, "Parse error at {}", self.position));

        //First print the token that we did not expect
        //There should really just be one unexpected message at this point though we print them
        //all to be safe
        let unexpected = self.errors.iter()
            .filter(|e| match **e { Error::Unexpected(_) => true, _ => false } );
        for error in unexpected {
            try!(writeln!(f, "{}", error));
        }

        //Then we print out all the things that were expected in a comma separated list
        //'Expected 'a', 'expression' or 'let'
        let expected_count = self.errors.iter()
            .filter(|e| match **e { Error::Expected(_) => true, _ => false } )
            .count();
        let mut i = 0;
        for error in self.errors.iter() {
            match *error {
                Error::Expected(ref message) => {
                    i += 1;
                    if i == 1 {
                        try!(write!(f, "Expected"));
                    }
                    else if i == expected_count {//Last expected message to be written
                        try!(write!(f, " or"));
                    }
                    else {
                        try!(write!(f, ","));
                    }
                    try!(write!(f, " '{}'", message));
                }
                _ => ()
            }
        }
        if expected_count != 0 {
            try!(writeln!(f, ""));
        }
        //If there are any generic messages we print them out last
        let messages = self.errors.iter()
            .filter(|e| match **e { Error::Message(_) | Error::Other(_) => true, _ => false } );
        for error in messages {
            try!(writeln!(f, "{}", error));
        }
        Ok(())
    }
}
impl fmt::Display for SourcePosition {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "line: {}, column: {}", self.line, self.column)
    }
}
impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Unexpected(c) => write!(f, "Unexpected character '{}'", c),
            Error::Expected(ref s) => write!(f, "Expected {}", s),
            Error::Message(ref msg) => write!(f, "{}", msg),
            Error::Other(ref err) => err.fmt(f)
        }
    }
}

///The `State<I>` struct keeps track of the current position in the stream `I`
#[derive(Clone, PartialEq, Debug)]
pub struct State<I> {
    pub position: SourcePosition,
    pub input: I
}

impl <I: Stream> State<I> {
    pub fn new(input: I) -> State<I> {
        State { position: SourcePosition::start(), input: input }
    }

    pub fn as_empty(&self) -> State<I> {
        State { position: self.position, input: self.input.clone() }
    }

    ///`uncons` is the most general way of extracting and item from a stream
    ///It takes a function `f` as argument which should update the position
    ///according to the item that was extracted
    ///Usually you want to use `uncons_char` instead which works directly on character streams
    pub fn uncons<F>(self, f: F) -> ParseResult<<I as Stream>::Item, I>
        where F: FnOnce(&mut SourcePosition, &<I as Stream>::Item) {
        let State { mut position, input, .. } = self;
        match input.uncons() {
            Ok((c, input)) => {
                f(&mut position, &c);
                Ok((c, Consumed::Consumed(State { position: position, input: input })))
            }
            Err(()) => Err(Consumed::Empty(ParseError::new(position, Error::Message("End of input".into()))))
        }
    }
}
impl <I: Stream<Item=char>> State<I> {
    ///Specialized uncons function for character streams which updates the position
    ///with no further action needed
    pub fn uncons_char(self) -> ParseResult<<I as Stream>::Item, I> {
        self.uncons(SourcePosition::update)
    }

}

///A type alias over the specific `Result` type used by parsers to indicate wether they were
///successful or not.
///`O` is the type that is output on success
///`I` is the specific stream type used in the parser
pub type ParseResult<O, I> = Result<(O, Consumed<State<I>>), Consumed<ParseError>>;

///A stream is a sequence of items that can be extracted one by one
pub trait Stream : Clone {
    type Item;
    ///Takes a stream and removes its first item, yielding the item and the rest of the elements
    ///Returns `Err` when no more elements could be retrieved
    fn uncons(self) -> Result<(Self::Item, Self), ()>;
}

impl <'a> Stream for &'a str {
    type Item = char;
    fn uncons(self) -> Result<(char, &'a str), ()> {
        match self.chars().next() {
            Some(c) => Ok((c, &self[c.len_utf8()..])),
            None => Err(())
        }
    }
}

impl <'a, T> Stream for &'a [T] {
    type Item = &'a T;
    fn uncons(self) -> Result<(&'a T, &'a [T]), ()> {
        if self.len() > 0 {
            Ok((&self[0], &self[1..]))
        }
        else {
            Err(())
        }
    }
}

#[derive(Clone, Debug)]
pub struct IteratorStream<I>(I)
    where I: Iterator + Clone;

///Converts an `Iterator` into a stream.
pub fn from_iter<I>(iter: I) -> IteratorStream<I>
    where I: Iterator + Clone {
    IteratorStream(iter)
}

impl <I: Iterator + Clone> Stream for IteratorStream<I> {
    type Item = <I as Iterator>::Item;
    fn uncons(mut self) -> Result<(I::Item, Self), ()> {
        match self.0.next() {
            Some(x) => Ok((x, self)),
            None => Err(())
        }
    }
}

///By implementing the `Parser` trait a type says that it can be used to parse an input stream into
///the type `Output`.
pub trait Parser {
    ///A type implementing the `Stream` trait which is the specific type
    ///that is parsed.
    type Input: Stream;
    ///The type which is returned when the parsing is successful.
    type Output;

    ///Entrypoint of the parser
    ///Takes some input and tries to parse it returning a `ParseResult`
    fn parse(&mut self, input: Self::Input) -> Result<(Self::Output, Self::Input), ParseError> {
        match self.parse_state(State::new(input)) {
            Ok((v, state)) => Ok((v, state.into_inner().input)),
            Err(error) => Err(error.into_inner())
        }
    }
    ///Parses using the state `input` by calling Stream::uncons one or more times
    ///On success returns `Ok((value, new_state))` on failure it returns `Err(error)`
    fn parse_state(&mut self, input: State<Self::Input>) -> ParseResult<Self::Output, Self::Input>;
}
impl <'a, I, O, P: ?Sized> Parser for &'a mut P
    where I: Stream, P: Parser<Input=I, Output=O> {
    type Input = I;
    type Output = O;
    fn parse_state(&mut self, input: State<I>) -> ParseResult<O, I> {
        (*self).parse_state(input)
    }
}
impl <I, O, P: ?Sized> Parser for Box<P>
    where I: Stream, P: Parser<Input=I, Output=O> {
    type Input = I;
    type Output = O;
    fn parse_state(&mut self, input: State<I>) -> ParseResult<O, I> {
        (**self).parse_state(input)
    }
}
<commit_msg>Make Error satisfy Send<commit_after>use std::fmt;
use std::borrow::Cow;
use std::error::Error as StdError;

///Struct which represents the positions in the source file
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct SourcePosition {
    ///Current line of the input
    pub line: i32,
    ///Current column of the input
    pub column: i32
}
impl SourcePosition {
    fn start() -> SourcePosition {
        SourcePosition { line: 1, column: 1 }
    }

    fn update(&mut self, c: &char) {
        self.column += 1;
        if *c == '\n' {
            self.column = 1;
            self.line += 1;
        }
    }
}

///Enum used to store information about an error that has occured
#[derive(Debug)]
pub enum Error {
    ///Error indicating an unexpected token has been encountered in the stream
    Unexpected(char),
    ///Error indicating that the parser expected something else
    Expected(Cow<'static, str>),
    ///Generic message
    Message(Cow<'static, str>),
    ///Variant for containing other types of errors
    Other(Box<StdError+Send>)
}

impl PartialEq for Error {
    fn eq(&self, other: &Error) -> bool {
        match (self, other) {
            (&Error::Unexpected(l), &Error::Unexpected(r)) => l == r,
            (&Error::Expected(ref l), &Error::Expected(ref r)) => l == r,
            (&Error::Message(ref l), &Error::Message(ref r)) => l == r,
            _ => false
        }
    }
}

impl <E> From<E> for Error where E: StdError + 'static + Send {
    fn from(e: E) -> Error {
        Error::Other(Box::new(e))
    }
}

///Enum used to indicate if a parser consumed any items of the stream it was given as an input
#[derive(Clone, PartialEq, Debug, Copy)]
pub enum Consumed<T> {
    ///Constructor indicating that the parser has consumed elements
    Consumed(T),
    ///Constructor indicating that the parser did not consume any elements
    Empty(T)
}

impl <T> Consumed<T> {

    ///Returns true if `self` is empty
    pub fn is_empty(&self) -> bool {
        match *self {
            Consumed::Empty(_) => true,
            Consumed::Consumed(_) => false
        }
    }

    ///Extracts the contained value
    pub fn into_inner(self) -> T {
        match self {
            Consumed::Empty(x) => x,
            Consumed::Consumed(x) => x
        }
    }

    ///Converts `self` into the Consumed state
    pub fn as_consumed(self) -> Consumed<T> {
        Consumed::Consumed(self.into_inner())
    }

    ///Converts `self` into theEmpty state
    pub fn as_empty(self) -> Consumed<T> {
        Consumed::Empty(self.into_inner())
    }

    ///Maps over the contained value without changing the consumed state
    pub fn map<F, U>(self, f: F) -> Consumed<U>
        where F: FnOnce(T) -> U {
        match self {
            Consumed::Empty(x) => Consumed::Empty(f(x)),
            Consumed::Consumed(x) => Consumed::Consumed(f(x))
        }
    }

    ///Combines the Consumed flags from `self` and the result of `f`
    ///
    ///```
    /// # extern crate parser_combinators as pc;
    /// # use pc::*;
    /// # use pc::primitives::State;
    /// # fn main() {
    /// //Parses a characther of string literal and handles the escaped characthers \\ and \" as \
    /// //and " respectively
    /// fn char(input: State<&str>) -> ParseResult<char, &str> {
    ///     let (c, input) = try!(satisfy(|c| c != '"').parse_state(input));
    ///     match c {
    ///         //Since the `char` parser has already consumed some of the input `combine` is used
    ///         //propagate the consumed state to the next part of the parser
    ///         '\\' => input.combine(|input| {
    ///             satisfy(|c| c == '"' || c == '\\')
    ///                 .map(|c| {
    ///                     match c {
    ///                         '"' => '"',
    ///                         '\\' => '\\',
    ///                         c => c
    ///                     }
    ///                 })
    ///                 .parse_state(input)
    ///             }),
    ///         _ => Ok((c, input))
    ///     }
    /// }
    /// let result = many(parser(char))
    ///     .parse(r#"abc\"\\"#);
    /// assert_eq!(result, Ok((r#"abc"\"#.to_string(), "")));
    /// }
    ///```
    pub fn combine<F, U, I>(self, f: F) -> ParseResult<U, I>
        where F: FnOnce(T) -> ParseResult<U, I> {
        match self {
            Consumed::Consumed(x) => {
                match f(x) {
                    Ok((v, Consumed::Empty(rest))) => Ok((v, Consumed::Consumed(rest))),
                    Err(Consumed::Empty(err)) => Err(Consumed::Consumed(err)),
                    y => y
                }
            }
            Consumed::Empty(x) => f(x)
        }
    }
}
///Struct which hold information about an error that occured at a specific position.
///Can hold multiple instances of `Error` if more that one error occured at the position.
#[derive(Debug, PartialEq)]
pub struct ParseError {
    ///The position where the error occured
    pub position: SourcePosition,
    ///A vector containing specific information on what errors occured at `position`
    pub errors: Vec<Error>
}

impl ParseError {
    pub fn new(position: SourcePosition, error: Error) -> ParseError {
        ParseError { position: position, errors: vec![error] }
    }
    pub fn add_message<S>(&mut self, message: S)
        where S: Into<Cow<'static, str>> {
        self.add_error(Error::Message(message.into()));
    }
    pub fn add_error(&mut self, message: Error) {
        //Don't add duplicate errors
        if self.errors.iter().find(|msg| **msg == message).is_none() {
            self.errors.push(message);
        }
    }
    pub fn set_expected(&mut self, message: Cow<'static, str>) {
        //Remove all other expected messages
        self.errors.retain(|e| match *e { Error::Expected(_) => false, _ => true });
        self.errors.push(Error::Expected(message));
    }
    pub fn merge(mut self, other: ParseError) -> ParseError {
        use std::cmp::Ordering;
        //Only keep the errors which occured after consuming the most amount of data
        match self.position.cmp(&other.position) {
            Ordering::Less => other,
            Ordering::Greater => self,
            Ordering::Equal => {
                for message in other.errors.into_iter() {
                    self.add_error(message);
                }
                self
            }
        }
    }
}

impl StdError for ParseError {
    fn description(&self) -> &str { "parse error" }
}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(writeln!(f, "Parse error at {}", self.position));

        //First print the token that we did not expect
        //There should really just be one unexpected message at this point though we print them
        //all to be safe
        let unexpected = self.errors.iter()
            .filter(|e| match **e { Error::Unexpected(_) => true, _ => false } );
        for error in unexpected {
            try!(writeln!(f, "{}", error));
        }

        //Then we print out all the things that were expected in a comma separated list
        //'Expected 'a', 'expression' or 'let'
        let expected_count = self.errors.iter()
            .filter(|e| match **e { Error::Expected(_) => true, _ => false } )
            .count();
        let mut i = 0;
        for error in self.errors.iter() {
            match *error {
                Error::Expected(ref message) => {
                    i += 1;
                    if i == 1 {
                        try!(write!(f, "Expected"));
                    }
                    else if i == expected_count {//Last expected message to be written
                        try!(write!(f, " or"));
                    }
                    else {
                        try!(write!(f, ","));
                    }
                    try!(write!(f, " '{}'", message));
                }
                _ => ()
            }
        }
        if expected_count != 0 {
            try!(writeln!(f, ""));
        }
        //If there are any generic messages we print them out last
        let messages = self.errors.iter()
            .filter(|e| match **e { Error::Message(_) | Error::Other(_) => true, _ => false } );
        for error in messages {
            try!(writeln!(f, "{}", error));
        }
        Ok(())
    }
}
impl fmt::Display for SourcePosition {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "line: {}, column: {}", self.line, self.column)
    }
}
impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Unexpected(c) => write!(f, "Unexpected character '{}'", c),
            Error::Expected(ref s) => write!(f, "Expected {}", s),
            Error::Message(ref msg) => write!(f, "{}", msg),
            Error::Other(ref err) => err.fmt(f)
        }
    }
}

///The `State<I>` struct keeps track of the current position in the stream `I`
#[derive(Clone, PartialEq, Debug)]
pub struct State<I> {
    pub position: SourcePosition,
    pub input: I
}

impl <I: Stream> State<I> {
    pub fn new(input: I) -> State<I> {
        State { position: SourcePosition::start(), input: input }
    }

    pub fn as_empty(&self) -> State<I> {
        State { position: self.position, input: self.input.clone() }
    }

    ///`uncons` is the most general way of extracting and item from a stream
    ///It takes a function `f` as argument which should update the position
    ///according to the item that was extracted
    ///Usually you want to use `uncons_char` instead which works directly on character streams
    pub fn uncons<F>(self, f: F) -> ParseResult<<I as Stream>::Item, I>
        where F: FnOnce(&mut SourcePosition, &<I as Stream>::Item) {
        let State { mut position, input, .. } = self;
        match input.uncons() {
            Ok((c, input)) => {
                f(&mut position, &c);
                Ok((c, Consumed::Consumed(State { position: position, input: input })))
            }
            Err(()) => Err(Consumed::Empty(ParseError::new(position, Error::Message("End of input".into()))))
        }
    }
}
impl <I: Stream<Item=char>> State<I> {
    ///Specialized uncons function for character streams which updates the position
    ///with no further action needed
    pub fn uncons_char(self) -> ParseResult<<I as Stream>::Item, I> {
        self.uncons(SourcePosition::update)
    }

}

///A type alias over the specific `Result` type used by parsers to indicate wether they were
///successful or not.
///`O` is the type that is output on success
///`I` is the specific stream type used in the parser
pub type ParseResult<O, I> = Result<(O, Consumed<State<I>>), Consumed<ParseError>>;

///A stream is a sequence of items that can be extracted one by one
pub trait Stream : Clone {
    type Item;
    ///Takes a stream and removes its first item, yielding the item and the rest of the elements
    ///Returns `Err` when no more elements could be retrieved
    fn uncons(self) -> Result<(Self::Item, Self), ()>;
}

impl <'a> Stream for &'a str {
    type Item = char;
    fn uncons(self) -> Result<(char, &'a str), ()> {
        match self.chars().next() {
            Some(c) => Ok((c, &self[c.len_utf8()..])),
            None => Err(())
        }
    }
}

impl <'a, T> Stream for &'a [T] {
    type Item = &'a T;
    fn uncons(self) -> Result<(&'a T, &'a [T]), ()> {
        if self.len() > 0 {
            Ok((&self[0], &self[1..]))
        }
        else {
            Err(())
        }
    }
}

#[derive(Clone, Debug)]
pub struct IteratorStream<I>(I)
    where I: Iterator + Clone;

///Converts an `Iterator` into a stream.
pub fn from_iter<I>(iter: I) -> IteratorStream<I>
    where I: Iterator + Clone {
    IteratorStream(iter)
}

impl <I: Iterator + Clone> Stream for IteratorStream<I> {
    type Item = <I as Iterator>::Item;
    fn uncons(mut self) -> Result<(I::Item, Self), ()> {
        match self.0.next() {
            Some(x) => Ok((x, self)),
            None => Err(())
        }
    }
}

///By implementing the `Parser` trait a type says that it can be used to parse an input stream into
///the type `Output`.
pub trait Parser {
    ///A type implementing the `Stream` trait which is the specific type
    ///that is parsed.
    type Input: Stream;
    ///The type which is returned when the parsing is successful.
    type Output;

    ///Entrypoint of the parser
    ///Takes some input and tries to parse it returning a `ParseResult`
    fn parse(&mut self, input: Self::Input) -> Result<(Self::Output, Self::Input), ParseError> {
        match self.parse_state(State::new(input)) {
            Ok((v, state)) => Ok((v, state.into_inner().input)),
            Err(error) => Err(error.into_inner())
        }
    }
    ///Parses using the state `input` by calling Stream::uncons one or more times
    ///On success returns `Ok((value, new_state))` on failure it returns `Err(error)`
    fn parse_state(&mut self, input: State<Self::Input>) -> ParseResult<Self::Output, Self::Input>;
}
impl <'a, I, O, P: ?Sized> Parser for &'a mut P
    where I: Stream, P: Parser<Input=I, Output=O> {
    type Input = I;
    type Output = O;
    fn parse_state(&mut self, input: State<I>) -> ParseResult<O, I> {
        (*self).parse_state(input)
    }
}
impl <I, O, P: ?Sized> Parser for Box<P>
    where I: Stream, P: Parser<Input=I, Output=O> {
    type Input = I;
    type Output = O;
    fn parse_state(&mut self, input: State<I>) -> ParseResult<O, I> {
        (**self).parse_state(input)
    }
}
<|endoftext|>