<commit_before>use std::num::{Zero, One, Algebraic};
use std::vec;
use std::vec::{VecIterator, VecMutIterator};
use std::cmp::ApproxEq;
use std::iterator::FromIterator;
use traits::iterable::{Iterable, IterableMut};
use traits::translation::Translation;
use traits::scalar_op::{ScalarAdd, ScalarSub};

/// Vector with a dimension unknown at compile-time.
#[deriving(Eq, ToStr, Clone)]
pub struct DVec<N> {
    /// Components of the vector. Contains as much elements as the vector dimension.
    at: ~[N]
}

impl<N: Zero + Clone> DVec<N> {
    /// Builds a vector filled with zeros.
    ///
    /// # Arguments
    ///   * `dim` - The dimension of the vector.
    #[inline]
    pub fn new_zeros(dim: uint) -> DVec<N> {
        DVec::from_elem(dim, Zero::zero())
    }

    /// Tests if all components of the vector are zeroes.
    #[inline]
    pub fn is_zero(&self) -> bool {
        self.at.iter().all(|e| e.is_zero())
    }
}

impl<N: One + Clone> DVec<N> {
    /// Builds a vector filled with ones.
    ///
    /// # Arguments
    ///   * `dim` - The dimension of the vector.
    #[inline]
    pub fn new_ones(dim: uint) -> DVec<N> {
        DVec::from_elem(dim, One::one())
    }
}

impl<N: Clone> DVec<N> {
    /// Builds a vector filled with a constant.
    #[inline]
    pub fn from_elem(dim: uint, elem: N) -> DVec<N> {
        DVec { at: vec::from_elem(dim, elem) }
    }
}

impl<N: Clone> DVec<N> {
    /// Builds a vector filled with the result of a function.
    #[inline(always)]
    pub fn from_fn(dim: uint, f: &fn(uint) -> N) -> DVec<N> {
        DVec { at: vec::from_fn(dim, |i| f(i)) }
    }
}

impl<N> Container for DVec<N> {
    #[inline]
    fn len(&self) -> uint {
        self.at.len()
    }
}

impl<N> Iterable<N> for DVec<N> {
    #[inline]
    fn iter<'l>(&'l self) -> VecIterator<'l, N> {
        self.at.iter()
    }
}

impl<N> IterableMut<N> for DVec<N> {
    #[inline]
    fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> {
        self.at.mut_iter()
    }
}

impl<N> FromIterator<N> for DVec<N> {
    #[inline]
    fn from_iterator<I: Iterator<N>>(mut param: &mut I) -> DVec<N> {
        let mut res = DVec { at: ~[] };

        for e in param {
            res.at.push(e)
        }

        res
    }
}

impl<N: Clone + Num + Algebraic + ApproxEq<N>> DVec<N> {
    /// Computes the canonical basis for the given dimension. A canonical basis is a set of
    /// vectors, mutually orthogonal, with all its component equal to 0.0 exept one which is equal
    /// to 1.0.
    pub fn canonical_basis_with_dim(dim: uint) -> ~[DVec<N>] {
        let mut res : ~[DVec<N>] = ~[];

        for i in range(0u, dim) {
            let mut basis_element : DVec<N> = DVec::new_zeros(dim);

            basis_element.at[i] = One::one();

            res.push(basis_element);
        }

        res
    }

    /// Computes a basis of the space orthogonal to the vector. If the input vector is of dimension
    /// `n`, this will return `n - 1` vectors.
    pub fn orthogonal_subspace_basis(&self) -> ~[DVec<N>] {
        // compute the basis of the orthogonal subspace using Gram-Schmidt
        // orthogonalization algorithm
        let     dim              = self.at.len();
        let mut res : ~[DVec<N>] = ~[];

        for i in range(0u, dim) {
            let mut basis_element : DVec<N> = DVec::new_zeros(self.at.len());

            basis_element.at[i] = One::one();

            if res.len() == dim - 1 {
                break;
            }

            let mut elt = basis_element.clone();

            elt = elt - self * basis_element.dot(self);

            for v in res.iter() {
                elt = elt - v * elt.dot(v)
            };

            if !elt.sqnorm().approx_eq(&Zero::zero()) {
                res.push(elt.normalized());
            }
        }

        assert!(res.len() == dim - 1);

        res
    }
}

impl<N: Add<N,N>> Add<DVec<N>, DVec<N>> for DVec<N> {
    #[inline]
    fn add(&self, other: &DVec<N>) -> DVec<N> {
        assert!(self.at.len() == other.at.len());
        DVec {
            at: self.at.iter().zip(other.at.iter()).map(|(a, b)| *a + *b).collect()
        }
    }
}

impl<N: Sub<N,N>> Sub<DVec<N>, DVec<N>> for DVec<N> {
    #[inline]
    fn sub(&self, other: &DVec<N>) -> DVec<N> {
        assert!(self.at.len() == other.at.len());
        DVec {
            at: self.at.iter().zip(other.at.iter()).map(|(a, b)| *a - *b).collect()
        }
    }
}

impl<N: Neg<N>> Neg<DVec<N>> for DVec<N> {
    #[inline]
    fn neg(&self) -> DVec<N> {
        DVec { at: self.at.iter().map(|a| -a).collect() }
    }
}

impl<N: Num> DVec<N> {
    /// Will change soon.
    #[inline]
    pub fn dot(&self, other: &DVec<N>) -> N {
        assert!(self.at.len() == other.at.len());

        let mut res: N = Zero::zero();

        for i in range(0u, self.at.len()) {
            res = res + self.at[i] * other.at[i];
        }

        res
    }

    /// Will change soon.
    #[inline]
    pub fn sub_dot(&self, a: &DVec<N>, b: &DVec<N>) -> N {
        let mut res: N = Zero::zero();

        for i in range(0u, self.at.len()) {
            res = res + (self.at[i] - a.at[i]) * b.at[i];
        }

        res
    }
}

impl<N: Mul<N, N>> Mul<N, DVec<N>> for DVec<N> {
    #[inline]
    fn mul(&self, s: &N) -> DVec<N> {
        DVec { at: self.at.iter().map(|a| a * *s).collect() }
    }
}

impl<N: Div<N, N>> Div<N, DVec<N>> for DVec<N> {
    #[inline]
    fn div(&self, s: &N) -> DVec<N> {
        DVec { at: self.at.iter().map(|a| a / *s).collect() }
    }
}

impl<N: Add<N, N>> ScalarAdd<N> for DVec<N> {
    #[inline]
    fn scalar_add(&self, s: &N) -> DVec<N> {
        DVec { at: self.at.iter().map(|a| a + *s).collect() }
    }

    #[inline]
    fn scalar_add_inplace(&mut self, s: &N) {
        for i in range(0u, self.at.len()) {
            self.at[i] = self.at[i] + *s;
        }
    }
}

impl<N: Sub<N, N>> ScalarSub<N> for DVec<N> {
    #[inline]
    fn scalar_sub(&self, s: &N) -> DVec<N> {
        DVec { at: self.at.iter().map(|a| a - *s).collect() }
    }

    #[inline]
    fn scalar_sub_inplace(&mut self, s: &N) {
        for i in range(0u, self.at.len()) {
            self.at[i] = self.at[i] - *s;
        }
    }
}

impl<N: Add<N, N> + Neg<N> + Clone> Translation<DVec<N>> for DVec<N> {
    #[inline]
    fn translation(&self) -> DVec<N> {
        self.clone()
    }

    #[inline]
    fn inv_translation(&self) -> DVec<N> {
        -self
    }

    #[inline]
    fn translate_by(&mut self, t: &DVec<N>) {
        *self = *self + *t;
    }

    #[inline]
    fn translated(&self, t: &DVec<N>) -> DVec<N> {
        self + *t
    }

    #[inline]
    fn set_translation(&mut self, t: DVec<N>) {
        *self = t
    }
}

impl<N: Num + Algebraic + Clone> DVec<N> {
    /// Will change soon.
    #[inline]
    pub fn sqnorm(&self) -> N {
        self.dot(self)
    }

    /// Will change soon.
    #[inline]
    pub fn norm(&self) -> N {
        self.sqnorm().sqrt()
    }

    /// Will change soon.
    #[inline]
    pub fn normalized(&self) -> DVec<N> {
        let mut res : DVec<N> = self.clone();

        res.normalize();

        res
    }

    /// Will change soon.
    #[inline]
    pub fn normalize(&mut self) -> N {
        let l = self.norm();

        for i in range(0u, self.at.len()) {
            self.at[i] = self.at[i] / l;
        }

        l
    }
}

impl<N: ApproxEq<N>> ApproxEq<N> for DVec<N> {
    #[inline]
    fn approx_epsilon() -> N {
        fail!("Fix me.")
        // let res: N = ApproxEq::<N>::approx_epsilon();

        // res
    }

    #[inline]
    fn approx_eq(&self, other: &DVec<N>) -> bool {
        let mut zip = self.at.iter().zip(other.at.iter());

        do zip.all |(a, b)| {
            a.approx_eq(b)
        }
    }

    #[inline]
    fn approx_eq_eps(&self, other: &DVec<N>, epsilon: &N) -> bool {
        let mut zip = self.at.iter().zip(other.at.iter());

        do zip.all |(a, b)| {
            a.approx_eq_eps(b, epsilon)
        }
    }
}
<commit_msg>Implement `Norm` and `Dot` for `DVec`.<commit_after>use std::num::{Zero, One, Algebraic};
use std::vec;
use std::vec::{VecIterator, VecMutIterator};
use std::cmp::ApproxEq;
use std::iterator::FromIterator;
use traits::dot::Dot;
use traits::norm::Norm;
use traits::iterable::{Iterable, IterableMut};
use traits::translation::Translation;
use traits::scalar_op::{ScalarAdd, ScalarSub};

/// Vector with a dimension unknown at compile-time.
#[deriving(Eq, ToStr, Clone)]
pub struct DVec<N> {
    /// Components of the vector. Contains as much elements as the vector dimension.
    at: ~[N]
}

impl<N: Zero + Clone> DVec<N> {
    /// Builds a vector filled with zeros.
    ///
    /// # Arguments
    ///   * `dim` - The dimension of the vector.
    #[inline]
    pub fn new_zeros(dim: uint) -> DVec<N> {
        DVec::from_elem(dim, Zero::zero())
    }

    /// Tests if all components of the vector are zeroes.
    #[inline]
    pub fn is_zero(&self) -> bool {
        self.at.iter().all(|e| e.is_zero())
    }
}

impl<N: One + Clone> DVec<N> {
    /// Builds a vector filled with ones.
    ///
    /// # Arguments
    ///   * `dim` - The dimension of the vector.
    #[inline]
    pub fn new_ones(dim: uint) -> DVec<N> {
        DVec::from_elem(dim, One::one())
    }
}

impl<N: Clone> DVec<N> {
    /// Builds a vector filled with a constant.
    #[inline]
    pub fn from_elem(dim: uint, elem: N) -> DVec<N> {
        DVec { at: vec::from_elem(dim, elem) }
    }
}

impl<N: Clone> DVec<N> {
    /// Builds a vector filled with the result of a function.
    #[inline(always)]
    pub fn from_fn(dim: uint, f: &fn(uint) -> N) -> DVec<N> {
        DVec { at: vec::from_fn(dim, |i| f(i)) }
    }
}

impl<N> Container for DVec<N> {
    #[inline]
    fn len(&self) -> uint {
        self.at.len()
    }
}

impl<N> Iterable<N> for DVec<N> {
    #[inline]
    fn iter<'l>(&'l self) -> VecIterator<'l, N> {
        self.at.iter()
    }
}

impl<N> IterableMut<N> for DVec<N> {
    #[inline]
    fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> {
        self.at.mut_iter()
    }
}

impl<N> FromIterator<N> for DVec<N> {
    #[inline]
    fn from_iterator<I: Iterator<N>>(mut param: &mut I) -> DVec<N> {
        let mut res = DVec { at: ~[] };

        for e in param {
            res.at.push(e)
        }

        res
    }
}

impl<N: Clone + Num + Algebraic + ApproxEq<N>> DVec<N> {
    /// Computes the canonical basis for the given dimension. A canonical basis is a set of
    /// vectors, mutually orthogonal, with all its component equal to 0.0 exept one which is equal
    /// to 1.0.
    pub fn canonical_basis_with_dim(dim: uint) -> ~[DVec<N>] {
        let mut res : ~[DVec<N>] = ~[];

        for i in range(0u, dim) {
            let mut basis_element : DVec<N> = DVec::new_zeros(dim);

            basis_element.at[i] = One::one();

            res.push(basis_element);
        }

        res
    }

    /// Computes a basis of the space orthogonal to the vector. If the input vector is of dimension
    /// `n`, this will return `n - 1` vectors.
    pub fn orthogonal_subspace_basis(&self) -> ~[DVec<N>] {
        // compute the basis of the orthogonal subspace using Gram-Schmidt
        // orthogonalization algorithm
        let     dim              = self.at.len();
        let mut res : ~[DVec<N>] = ~[];

        for i in range(0u, dim) {
            let mut basis_element : DVec<N> = DVec::new_zeros(self.at.len());

            basis_element.at[i] = One::one();

            if res.len() == dim - 1 {
                break;
            }

            let mut elt = basis_element.clone();

            elt = elt - self * basis_element.dot(self);

            for v in res.iter() {
                elt = elt - v * elt.dot(v)
            };

            if !elt.sqnorm().approx_eq(&Zero::zero()) {
                res.push(elt.normalized());
            }
        }

        assert!(res.len() == dim - 1);

        res
    }
}

impl<N: Add<N,N>> Add<DVec<N>, DVec<N>> for DVec<N> {
    #[inline]
    fn add(&self, other: &DVec<N>) -> DVec<N> {
        assert!(self.at.len() == other.at.len());
        DVec {
            at: self.at.iter().zip(other.at.iter()).map(|(a, b)| *a + *b).collect()
        }
    }
}

impl<N: Sub<N,N>> Sub<DVec<N>, DVec<N>> for DVec<N> {
    #[inline]
    fn sub(&self, other: &DVec<N>) -> DVec<N> {
        assert!(self.at.len() == other.at.len());
        DVec {
            at: self.at.iter().zip(other.at.iter()).map(|(a, b)| *a - *b).collect()
        }
    }
}

impl<N: Neg<N>> Neg<DVec<N>> for DVec<N> {
    #[inline]
    fn neg(&self) -> DVec<N> {
        DVec { at: self.at.iter().map(|a| -a).collect() }
    }
}

impl<N: Num> Dot<N> for DVec<N> {
    #[inline]
    fn dot(&self, other: &DVec<N>) -> N {
        assert!(self.at.len() == other.at.len());

        let mut res: N = Zero::zero();

        for i in range(0u, self.at.len()) {
            res = res + self.at[i] * other.at[i];
        }

        res
    }

    #[inline]
    fn sub_dot(&self, a: &DVec<N>, b: &DVec<N>) -> N {
        let mut res: N = Zero::zero();

        for i in range(0u, self.at.len()) {
            res = res + (self.at[i] - a.at[i]) * b.at[i];
        }

        res
    }
}

impl<N: Mul<N, N>> Mul<N, DVec<N>> for DVec<N> {
    #[inline]
    fn mul(&self, s: &N) -> DVec<N> {
        DVec { at: self.at.iter().map(|a| a * *s).collect() }
    }
}

impl<N: Div<N, N>> Div<N, DVec<N>> for DVec<N> {
    #[inline]
    fn div(&self, s: &N) -> DVec<N> {
        DVec { at: self.at.iter().map(|a| a / *s).collect() }
    }
}

impl<N: Add<N, N>> ScalarAdd<N> for DVec<N> {
    #[inline]
    fn scalar_add(&self, s: &N) -> DVec<N> {
        DVec { at: self.at.iter().map(|a| a + *s).collect() }
    }

    #[inline]
    fn scalar_add_inplace(&mut self, s: &N) {
        for i in range(0u, self.at.len()) {
            self.at[i] = self.at[i] + *s;
        }
    }
}

impl<N: Sub<N, N>> ScalarSub<N> for DVec<N> {
    #[inline]
    fn scalar_sub(&self, s: &N) -> DVec<N> {
        DVec { at: self.at.iter().map(|a| a - *s).collect() }
    }

    #[inline]
    fn scalar_sub_inplace(&mut self, s: &N) {
        for i in range(0u, self.at.len()) {
            self.at[i] = self.at[i] - *s;
        }
    }
}

impl<N: Add<N, N> + Neg<N> + Clone> Translation<DVec<N>> for DVec<N> {
    #[inline]
    fn translation(&self) -> DVec<N> {
        self.clone()
    }

    #[inline]
    fn inv_translation(&self) -> DVec<N> {
        -self
    }

    #[inline]
    fn translate_by(&mut self, t: &DVec<N>) {
        *self = *self + *t;
    }

    #[inline]
    fn translated(&self, t: &DVec<N>) -> DVec<N> {
        self + *t
    }

    #[inline]
    fn set_translation(&mut self, t: DVec<N>) {
        *self = t
    }
}

impl<N: Num + Algebraic + Clone> Norm<N> for DVec<N> {
    #[inline]
    fn sqnorm(&self) -> N {
        self.dot(self)
    }

    #[inline]
    fn norm(&self) -> N {
        self.sqnorm().sqrt()
    }

    #[inline]
    fn normalized(&self) -> DVec<N> {
        let mut res : DVec<N> = self.clone();

        res.normalize();

        res
    }

    #[inline]
    fn normalize(&mut self) -> N {
        let l = self.norm();

        for i in range(0u, self.at.len()) {
            self.at[i] = self.at[i] / l;
        }

        l
    }
}

impl<N: ApproxEq<N>> ApproxEq<N> for DVec<N> {
    #[inline]
    fn approx_epsilon() -> N {
        fail!("Fix me.")
        // let res: N = ApproxEq::<N>::approx_epsilon();

        // res
    }

    #[inline]
    fn approx_eq(&self, other: &DVec<N>) -> bool {
        let mut zip = self.at.iter().zip(other.at.iter());

        do zip.all |(a, b)| {
            a.approx_eq(b)
        }
    }

    #[inline]
    fn approx_eq_eps(&self, other: &DVec<N>, epsilon: &N) -> bool {
        let mut zip = self.at.iter().zip(other.at.iter());

        do zip.all |(a, b)| {
            a.approx_eq_eps(b, epsilon)
        }
    }
}
<|endoftext|>


<commit_before>use std::convert::TryFrom;

use log::trace;
use nom::{
    branch::permutation,
    bytes::streaming::take,
    combinator::{complete, flat_map, map, map_parser, opt, verify},
    number::streaming::{be_f32, be_f64},
    sequence::{pair, preceded},
    Err, IResult, Needed, Parser,
};

#[derive(Debug, PartialEq)]
pub struct Error<'a> {
    input: &'a [u8],
    kind: ErrorKind,
}

#[derive(Debug, PartialEq)]
pub enum ErrorKind {
    Nom(nom::error::ErrorKind),
    Custom(u8),
}

impl<'a> nom::error::ParseError<&'a [u8]> for Error<'a> {
    fn from_error_kind(input: &'a [u8], kind: nom::error::ErrorKind) -> Self {
        Error {
            input,
            kind: ErrorKind::Nom(kind),
        }
    }

    fn append(_input: &'a [u8], _kind: nom::error::ErrorKind, other: Self) -> Self {
        other
    }
}

pub fn custom_error(input: &[u8], code: u8) -> Error {
    Error {
        input,
        kind: ErrorKind::Custom(code),
    }
}

pub(crate) fn usize_error(input: &[u8], size: u64) -> Result<usize, nom::Err<Error>> {
    usize::try_from(size).map_err(|_| {
        log::error!("Not possible to convert size into usize");
        nom::Err::Error(custom_error(input, 0))
    })
}

pub fn vint(input: &[u8]) -> IResult<&[u8], u64, Error> {
    if input.is_empty() {
        return Err(Err::Incomplete(Needed::new(1)));
    }

    let v = input[0];
    let len = v.leading_zeros();

    if len == 8 {
        return Err(Err::Error(custom_error(input, 100)));
    }

    if input.len() <= len as usize {
        return Err(Err::Incomplete(Needed::new(1)));
    }

    let mut val = u64::from(v ^ (1 << (7 - len)));

    trace!(
        "vint {:08b} {:08b} {:08b} {}",
        val,
        v,
        (1 << (8 - len)),
        len
    );

    for i in 0..len as usize {
        val = (val << 8) | u64::from(input[i + 1]);
    }

    trace!("     result {:08x}", val);

    Ok((&input[len as usize + 1..], val))
}

// The ID are represented in the specification as their binary representation
// do not drop the marker bit.
pub fn vid(input: &[u8]) -> IResult<&[u8], u64, Error> {
    if input.is_empty() {
        return Err(Err::Incomplete(Needed::new(1)));
    }

    let v = input[0];
    let len = v.leading_zeros();

    if len == 8 {
        return Err(Err::Error(custom_error(input, 100)));
    }

    if input.len() <= len as usize {
        return Err(Err::Incomplete(Needed::new(1)));
    }

    let mut val = u64::from(v);

    trace!("vid {:08b} {:08b} {:08b} {}", val, v, (1 << (8 - len)), len);

    for i in 0..len as usize {
        val = (val << 8) | u64::from(input[i + 1]);
    }

    trace!("     result {:08x}", val);

    Ok((&input[len as usize + 1..], val))
}

pub fn parse_uint_data(size: u64) -> impl Fn(&[u8]) -> IResult<&[u8], u64, Error> {
    move |input| {
        let mut val = 0;

        if size > 8 {
            return Err(Err::Error(custom_error(input, 102)));
        }

        for i in input.iter().take(size as usize) {
            val = (val << 8) | u64::from(*i);
        }

        Ok((&input[size as usize..], val))
    }
}

pub fn parse_int_data(size: u64) -> impl Fn(&[u8]) -> IResult<&[u8], i64, Error> {
    move |input| {
        let mut val = 0;

        if size > 8 {
            return Err(Err::Error(custom_error(input, 103)));
        }

        for i in input.iter().take(size as usize) {
            val = (val << 8) | u64::from(*i);
        }

        Ok((&input[size as usize..], val as i64))
    }
}

pub fn parse_str_data(size: u64) -> impl Fn(&[u8]) -> IResult<&[u8], String, Error> {
    move |input| {
        take(usize_error(input, size)?)(input).and_then(|(i, data)| {
            match String::from_utf8(data.to_owned()) {
                Ok(s) => Ok((i, s)),
                Err(_) => return Err(Err::Error(custom_error(i, 104))),
            }
        })
    }
}

pub fn parse_binary_data(size: u64) -> impl Fn(&[u8]) -> IResult<&[u8], Vec<u8>, Error> {
    move |input| {
        map(take(usize_error(input, size)?), |data: &[u8]| {
            data.to_owned()
        })(input)
    }
}

//FIXME: handle default values
//FIXME: is that really following IEEE_754-1985 ?
pub fn parse_float_data(size: u64) -> impl Fn(&[u8]) -> IResult<&[u8], f64, Error> {
    move |input| {
        if size == 0 {
            Ok((input, 0f64))
        } else if size == 4 {
            map(map_parser(take(4usize), be_f32), f64::from)(input)
        } else if size == 8 {
            map_parser(take(8usize), be_f64)(input)
        } else {
            Err(Err::Error(custom_error(input, 104)))
        }
    }
}

fn compute_ebml_type<'a, G, H, O1>(
    id: u64,
    second: G,
) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], O1, Error>
where
    G: Fn(u64) -> H,
    H: Parser<&'a [u8], O1, Error<'a>>,
{
    move |i| {
        flat_map(pair(verify(vid, |val| *val == id), vint), |(_, size)| {
            second(size)
        })(i)
    }
}

pub fn ebml_uint<'a>(id: u64) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], u64, Error> {
    compute_ebml_type(id, parse_uint_data)
}

pub fn ebml_int<'a>(id: u64) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], i64, Error> {
    compute_ebml_type(id, parse_int_data)
}

pub fn ebml_float<'a>(id: u64) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], f64, Error> {
    compute_ebml_type(id, parse_float_data)
}

pub fn ebml_str<'a>(id: u64) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], String, Error> {
    compute_ebml_type(id, parse_str_data)
}

pub fn ebml_binary<'a>(id: u64) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], Vec<u8>, Error> {
    compute_ebml_type(id, parse_binary_data)
}

pub fn ebml_binary_ref(id: u64) -> impl Fn(&[u8]) -> IResult<&[u8], &[u8], Error> {
    move |i| {
        pair(verify(vid, |val| *val == id), vint)(i)
            .and_then(|(i, (_, size))| take(usize_error(i, size)?)(i))
    }
}

pub fn ebml_master<'a, G, O1>(
    id: u64,
    second: G,
) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], O1, Error>
where
    G: Fn(&'a [u8]) -> IResult<&'a [u8], O1, Error> + Copy,
{
    move |i| {
        pair(verify(vid, |val| *val == id), vint)(i)
            .and_then(|(i, (_, size))| map_parser(take(usize_error(i, size)?), second)(i))
    }
}

pub fn eat_void<'a, G, O1>(second: G) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], O1, Error<'a>>
where
    G: Parser<&'a [u8], O1, Error<'a>> + Copy,
{
    move |i| preceded(opt(skip_void), second)(i)
}

pub fn skip_void(input: &[u8]) -> IResult<&[u8], &[u8], Error> {
    pair(verify(vid, |val| *val == 0xEC), vint)(input)
        .and_then(|(i, (_, size))| take(usize_error(input, size)?)(i))
}

#[derive(Debug, Clone, PartialEq)]
pub struct EBMLHeader {
    pub version: u64,
    pub read_version: u64,
    pub max_id_length: u64,
    pub max_size_length: u64,
    pub doc_type: String,
    pub doc_type_version: u64,
    pub doc_type_read_version: u64,
}

pub fn ebml_header(input: &[u8]) -> IResult<&[u8], EBMLHeader, Error> {
    ebml_master(0x1A45DFA3, |i| {
        map(
            permutation((
                ebml_uint(0x4286), // version
                ebml_uint(0x42F7), // read_version
                ebml_uint(0x42F2), // max id length
                ebml_uint(0x42F3), // max size length
                ebml_str(0x4282),  // doctype
                ebml_uint(0x4287), // doctype version
                ebml_uint(0x4285), // doctype_read version
                opt(complete(skip_void)),
            )),
            |t| EBMLHeader {
                version: t.0,
                read_version: t.1,
                max_id_length: t.2,
                max_size_length: t.3,
                doc_type: t.4,
                doc_type_version: t.5,
                doc_type_read_version: t.6,
            },
        )(i)
    })(input)
}

#[cfg(test)]
#[allow(non_upper_case_globals)]
mod tests {
    use log::trace;
    use nom::{HexDisplay, Offset};

    use super::*;

    const single_stream: &[u8] = include_bytes!("../assets/single_stream.mkv");
    const webm: &[u8] = include_bytes!("../assets/big-buck-bunny_trailer.webm");

    #[test]
    fn variable_integer() {
        let val01 = [0b10000000];

        match vint(&val01) {
            Ok((_, v)) => assert!(0 == v),
            _ => panic!(),
        }
    }

    #[test]
    fn mkv_header() {
        trace!("{}", single_stream[..8].to_hex(8));
        trace!("{:b} {:b}", single_stream[0], single_stream[1]);
        trace!("{:?}", ebml_header(&single_stream[..100]).unwrap());
    }

    #[test]
    fn webm_header() {
        trace!("{}", webm[..8].to_hex(8));
        let res = ebml_header(&webm[..100]);
        trace!("{:?}", res);

        if let Ok((i, _)) = res {
            trace!("offset: {} bytes", webm.offset(i));
        } else {
            panic!();
        }
    }
}
<commit_msg>Implement a more consistent ebml_binary_ref<commit_after>use std::convert::TryFrom;

use log::trace;
use nom::{
    branch::permutation,
    bytes::streaming::take,
    combinator::{complete, flat_map, map, map_parser, opt, verify},
    number::streaming::{be_f32, be_f64},
    sequence::{pair, preceded},
    Err, IResult, Needed, Parser,
};

#[derive(Debug, PartialEq)]
pub struct Error<'a> {
    input: &'a [u8],
    kind: ErrorKind,
}

#[derive(Debug, PartialEq)]
pub enum ErrorKind {
    Nom(nom::error::ErrorKind),
    Custom(u8),
}

impl<'a> nom::error::ParseError<&'a [u8]> for Error<'a> {
    fn from_error_kind(input: &'a [u8], kind: nom::error::ErrorKind) -> Self {
        Error {
            input,
            kind: ErrorKind::Nom(kind),
        }
    }

    fn append(_input: &'a [u8], _kind: nom::error::ErrorKind, other: Self) -> Self {
        other
    }
}

pub fn custom_error(input: &[u8], code: u8) -> Error {
    Error {
        input,
        kind: ErrorKind::Custom(code),
    }
}

pub(crate) fn usize_error(input: &[u8], size: u64) -> Result<usize, nom::Err<Error>> {
    usize::try_from(size).map_err(|_| {
        log::error!("Not possible to convert size into usize");
        nom::Err::Error(custom_error(input, 0))
    })
}

pub fn vint(input: &[u8]) -> IResult<&[u8], u64, Error> {
    if input.is_empty() {
        return Err(Err::Incomplete(Needed::new(1)));
    }

    let v = input[0];
    let len = v.leading_zeros();

    if len == 8 {
        return Err(Err::Error(custom_error(input, 100)));
    }

    if input.len() <= len as usize {
        return Err(Err::Incomplete(Needed::new(1)));
    }

    let mut val = u64::from(v ^ (1 << (7 - len)));

    trace!(
        "vint {:08b} {:08b} {:08b} {}",
        val,
        v,
        (1 << (8 - len)),
        len
    );

    for i in 0..len as usize {
        val = (val << 8) | u64::from(input[i + 1]);
    }

    trace!("     result {:08x}", val);

    Ok((&input[len as usize + 1..], val))
}

// The ID are represented in the specification as their binary representation
// do not drop the marker bit.
pub fn vid(input: &[u8]) -> IResult<&[u8], u64, Error> {
    if input.is_empty() {
        return Err(Err::Incomplete(Needed::new(1)));
    }

    let v = input[0];
    let len = v.leading_zeros();

    if len == 8 {
        return Err(Err::Error(custom_error(input, 100)));
    }

    if input.len() <= len as usize {
        return Err(Err::Incomplete(Needed::new(1)));
    }

    let mut val = u64::from(v);

    trace!("vid {:08b} {:08b} {:08b} {}", val, v, (1 << (8 - len)), len);

    for i in 0..len as usize {
        val = (val << 8) | u64::from(input[i + 1]);
    }

    trace!("     result {:08x}", val);

    Ok((&input[len as usize + 1..], val))
}

pub fn parse_uint_data(size: u64) -> impl Fn(&[u8]) -> IResult<&[u8], u64, Error> {
    move |input| {
        let mut val = 0;

        if size > 8 {
            return Err(Err::Error(custom_error(input, 102)));
        }

        for i in input.iter().take(size as usize) {
            val = (val << 8) | u64::from(*i);
        }

        Ok((&input[size as usize..], val))
    }
}

pub fn parse_int_data(size: u64) -> impl Fn(&[u8]) -> IResult<&[u8], i64, Error> {
    move |input| {
        let mut val = 0;

        if size > 8 {
            return Err(Err::Error(custom_error(input, 103)));
        }

        for i in input.iter().take(size as usize) {
            val = (val << 8) | u64::from(*i);
        }

        Ok((&input[size as usize..], val as i64))
    }
}

pub fn parse_str_data(size: u64) -> impl Fn(&[u8]) -> IResult<&[u8], String, Error> {
    move |input| {
        take(usize_error(input, size)?)(input).and_then(|(i, data)| {
            match String::from_utf8(data.to_owned()) {
                Ok(s) => Ok((i, s)),
                Err(_) => return Err(Err::Error(custom_error(i, 104))),
            }
        })
    }
}

pub fn parse_binary_data(size: u64) -> impl Fn(&[u8]) -> IResult<&[u8], Vec<u8>, Error> {
    move |input| {
        map(take(usize_error(input, size)?), |data: &[u8]| {
            data.to_owned()
        })(input)
    }
}

pub fn parse_binary_data_ref(size: u64) -> impl Fn(&[u8]) -> IResult<&[u8], &[u8], Error> {
    move |input| map(take(usize_error(input, size)?), |data| data)(input)
}

//FIXME: handle default values
//FIXME: is that really following IEEE_754-1985 ?
pub fn parse_float_data(size: u64) -> impl Fn(&[u8]) -> IResult<&[u8], f64, Error> {
    move |input| {
        if size == 0 {
            Ok((input, 0f64))
        } else if size == 4 {
            map(map_parser(take(4usize), be_f32), f64::from)(input)
        } else if size == 8 {
            map_parser(take(8usize), be_f64)(input)
        } else {
            Err(Err::Error(custom_error(input, 104)))
        }
    }
}

fn compute_ebml_type<'a, G, H, O1>(
    id: u64,
    second: G,
) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], O1, Error>
where
    G: Fn(u64) -> H,
    H: Parser<&'a [u8], O1, Error<'a>>,
{
    move |i| {
        flat_map(pair(verify(vid, |val| *val == id), vint), |(_, size)| {
            second(size)
        })(i)
    }
}

pub fn ebml_uint<'a>(id: u64) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], u64, Error> {
    compute_ebml_type(id, parse_uint_data)
}

pub fn ebml_int<'a>(id: u64) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], i64, Error> {
    compute_ebml_type(id, parse_int_data)
}

pub fn ebml_float<'a>(id: u64) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], f64, Error> {
    compute_ebml_type(id, parse_float_data)
}

pub fn ebml_str<'a>(id: u64) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], String, Error> {
    compute_ebml_type(id, parse_str_data)
}

pub fn ebml_binary<'a>(id: u64) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], Vec<u8>, Error> {
    compute_ebml_type(id, parse_binary_data)
}

pub fn ebml_binary_ref<'a>(id: u64) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], &'a [u8], Error> {
    compute_ebml_type(id, parse_binary_data_ref)
}

pub fn ebml_master<'a, G, O1>(
    id: u64,
    second: G,
) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], O1, Error>
where
    G: Fn(&'a [u8]) -> IResult<&'a [u8], O1, Error> + Copy,
{
    move |i| {
        pair(verify(vid, |val| *val == id), vint)(i)
            .and_then(|(i, (_, size))| map_parser(take(usize_error(i, size)?), second)(i))
    }
}

pub fn eat_void<'a, G, O1>(second: G) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], O1, Error<'a>>
where
    G: Parser<&'a [u8], O1, Error<'a>> + Copy,
{
    move |i| preceded(opt(skip_void), second)(i)
}

pub fn skip_void(input: &[u8]) -> IResult<&[u8], &[u8], Error> {
    pair(verify(vid, |val| *val == 0xEC), vint)(input)
        .and_then(|(i, (_, size))| take(usize_error(input, size)?)(i))
}

#[derive(Debug, Clone, PartialEq)]
pub struct EBMLHeader {
    pub version: u64,
    pub read_version: u64,
    pub max_id_length: u64,
    pub max_size_length: u64,
    pub doc_type: String,
    pub doc_type_version: u64,
    pub doc_type_read_version: u64,
}

pub fn ebml_header(input: &[u8]) -> IResult<&[u8], EBMLHeader, Error> {
    ebml_master(0x1A45DFA3, |i| {
        map(
            permutation((
                ebml_uint(0x4286), // version
                ebml_uint(0x42F7), // read_version
                ebml_uint(0x42F2), // max id length
                ebml_uint(0x42F3), // max size length
                ebml_str(0x4282),  // doctype
                ebml_uint(0x4287), // doctype version
                ebml_uint(0x4285), // doctype_read version
                opt(complete(skip_void)),
            )),
            |t| EBMLHeader {
                version: t.0,
                read_version: t.1,
                max_id_length: t.2,
                max_size_length: t.3,
                doc_type: t.4,
                doc_type_version: t.5,
                doc_type_read_version: t.6,
            },
        )(i)
    })(input)
}

#[cfg(test)]
#[allow(non_upper_case_globals)]
mod tests {
    use log::trace;
    use nom::{HexDisplay, Offset};

    use super::*;

    const single_stream: &[u8] = include_bytes!("../assets/single_stream.mkv");
    const webm: &[u8] = include_bytes!("../assets/big-buck-bunny_trailer.webm");

    #[test]
    fn variable_integer() {
        let val01 = [0b10000000];

        match vint(&val01) {
            Ok((_, v)) => assert!(0 == v),
            _ => panic!(),
        }
    }

    #[test]
    fn mkv_header() {
        trace!("{}", single_stream[..8].to_hex(8));
        trace!("{:b} {:b}", single_stream[0], single_stream[1]);
        trace!("{:?}", ebml_header(&single_stream[..100]).unwrap());
    }

    #[test]
    fn webm_header() {
        trace!("{}", webm[..8].to_hex(8));
        let res = ebml_header(&webm[..100]);
        trace!("{:?}", res);

        if let Ok((i, _)) = res {
            trace!("offset: {} bytes", webm.offset(i));
        } else {
            panic!();
        }
    }
}
<|endoftext|>


<commit_before>use luminance::{Dim2, Flat, RGBA32F, Texture};

/// Time.
pub type Time = f32;

/// A clip is an object that implements a visual sequence.
pub struct Clip<'a> {
  act: Box<Fn(Time) -> &'a Texture<Flat, Dim2, RGBA32F> + 'a>
}

impl<'a> Clip<'a> {
  pub fn new<F>(act: F) -> Self where F: 'a + Fn(Time) -> &'a Texture<Flat, Dim2, RGBA32F> {
    Clip {
      act: Box::new(act)
    }
  }
}

/// A cut is an object that slices a `Clip` at an *input time* and *output time*. It is instantiated
/// in a `Track` at a given *instance time*.
#[derive(Clone)]
pub struct Cut<'a> {
  pub in_time: Time,
  pub out_time: Time,
  pub inst_time: Time,
  pub clip: &'a Clip<'a>
}

impl<'a> Cut<'a> {
  pub fn new(in_time: Time, out_time: Time, inst_time: Time, clip: &'a Clip<'a>) -> Self {
    assert!(in_time <= out_time);

    Cut {
      in_time: in_time,
      out_time: out_time,
      inst_time: inst_time,
      clip: clip
    }
  }

  /// Duration of the cut.
  pub fn dur(&self) -> Time {
    self.out_time - self.in_time
  }
}

/// A track gathers `Cut`s and its purpose is to be used inside a `Timeline`.
#[derive(Clone)]
pub struct Track<'a> {
  cuts: Vec<Cut<'a>>
}

impl<'a> Track<'a> {
  pub fn new() -> Self {
    Track {
      cuts: Vec::new()
    }
  }

  pub fn add_cut(&mut self, cut: Cut<'a>) {
    self.cuts.push(cut);
  }
}

impl<'a, 'b> From<&'b [Cut<'a>]> for Track<'a> {
  fn from(cuts: &'b [Cut<'a>]) -> Self {
    Track {
      cuts: cuts.to_vec()
    }
  }
}

/// A timeline gathers tracks used to build up the visual aspect of the demo.
#[derive(Clone)]
pub struct Timeline<'a> {
  tracks: Vec<Track<'a>>,
}

impl<'a> Timeline<'a> {
  pub fn new() -> Self {
    Timeline {
      tracks: Vec::new(),
    }
  }

  pub fn add_track(&mut self, track: Track<'a>) {
    self.tracks.push(track);
  }

  // TODO: currently, we play the first track we find; add transition support
  pub fn play(&self, t: Time) -> Option<&'a Texture<Flat, Dim2, RGBA32F>> {
    for track in &self.tracks {
      for cut in &track.cuts {
        if cut.inst_time <= t && t <= cut.inst_time + cut.dur() {
          return Some((cut.clip.act)(t));
        }
      }
    }

    None
  }
}

impl<'a, 'b> From<&'b [Track<'a>]> for Timeline<'a> {
  fn from(tracks: &'b [Track<'a>]) -> Self {
    Timeline {
      tracks: tracks.to_vec(),
    }
  }
}
<commit_msg>Added lifetimes to edit.rs EVERY–FUCKING–WHERE!<commit_after>use luminance::{Dim2, Flat, RGBA32F, Texture};

/// Time.
pub type Time = f32;

/// A clip is an object that implements a visual sequence.
pub struct Clip<'a, 'b> where 'a: 'b {
  act: Box<Fn(Time) -> &'a Texture<Flat, Dim2, RGBA32F> + 'b>
}

impl<'a, 'b> Clip<'a, 'b> {
  pub fn new<F>(act: F) -> Self where F: 'b + Fn(Time) -> &'a Texture<Flat, Dim2, RGBA32F> {
    Clip {
      act: Box::new(act)
    }
  }
}

/// A cut is an object that slices a `Clip` at an *input time* and *output time*. It is instantiated
/// in a `Track` at a given *instance time*.
#[derive(Clone)]
pub struct Cut<'a, 'b, 'c> where 'a: 'b, 'b: 'c {
  pub in_time: Time,
  pub out_time: Time,
  pub inst_time: Time,
  pub clip: &'c Clip<'a, 'b>
}

impl<'a, 'b, 'c> Cut<'a, 'b, 'c> where 'a: 'b, 'b: 'c {
  pub fn new(in_time: Time, out_time: Time, inst_time: Time, clip: &'c Clip<'a, 'b>) -> Self {
    assert!(in_time <= out_time);

    Cut {
      in_time: in_time,
      out_time: out_time,
      inst_time: inst_time,
      clip: clip
    }
  }

  /// Duration of the cut.
  pub fn dur(&self) -> Time {
    self.out_time - self.in_time
  }
}

/// A track gathers `Cut`s and its purpose is to be used inside a `Timeline`.
#[derive(Clone)]
pub struct Track<'a, 'b, 'c> where 'a: 'b, 'b: 'c {
  cuts: Vec<Cut<'a, 'b, 'c>>
}

impl<'a, 'b, 'c> Track<'a, 'b, 'c> where 'a: 'b, 'b: 'c {
  pub fn new() -> Self {
    Track {
      cuts: Vec::new()
    }
  }

  pub fn add_cut(&mut self, cut: Cut<'a, 'b, 'c>) {
    self.cuts.push(cut);
  }
}

impl<'a, 'b, 'c, 'd> From<&'d [Cut<'a, 'b, 'c>]> for Track<'a, 'b, 'c> {
  fn from(cuts: &'d [Cut<'a, 'b, 'c>]) -> Self {
    Track {
      cuts: cuts.to_vec()
    }
  }
}

/// A timeline gathers tracks used to build up the visual aspect of the demo.
#[derive(Clone)]
pub struct Timeline<'a, 'b, 'c> where 'a: 'b, 'b: 'c {
  tracks: Vec<Track<'a, 'b, 'c>>,
}

impl<'a, 'b, 'c> Timeline<'a, 'b, 'c> where 'a: 'b, 'b: 'c {
  pub fn new() -> Self {
    Timeline {
      tracks: Vec::new(),
    }
  }

  pub fn add_track(&mut self, track: Track<'a, 'b, 'c>) {
    self.tracks.push(track);
  }

  // TODO: currently, we play the first track we find; add transition support
  pub fn play(&self, t: Time) -> Option<&'a Texture<Flat, Dim2, RGBA32F>> {
    for track in &self.tracks {
      for cut in &track.cuts {
        if cut.inst_time <= t && t <= cut.inst_time + cut.dur() {
          return Some((cut.clip.act)(t));
        }
      }
    }

    None
  }
}

impl<'a, 'b, 'c, 'd> From<&'d [Track<'a, 'b, 'c>]> for Timeline<'a, 'b, 'c> {
  fn from(tracks: &'d [Track<'a, 'b, 'c>]) -> Self {
    Timeline {
      tracks: tracks.to_vec(),
    }
  }
}
<|endoftext|>


<commit_before>use ast::{Ast, AstTrait};
use token::{TokenTrait, Type};
use builtins;
use std::ops::IndexMut;
use std::cmp::Ordering;

pub struct Eval {
    ast: Ast,
    stack: Vec<(Ast, usize)>,
    evaluated: bool
}

pub trait EvalTrait {
    fn eval(&mut self);
    fn is_evaluated(&self) -> bool;
}

pub trait PrettyPrint {
    fn pretty_print(&mut self) -> String;
    fn push_whitespace(&self, pretty: &mut String);
}

impl PrettyPrint for Eval {
    fn push_whitespace(&self, pretty: &mut String) {
        for _ in 0..self.stack.len() {
            pretty.push('\t');
        }
    }

    fn pretty_print(&mut self) -> String {
        let mut pretty = String::new();
        loop {
            match self.stack.pop() {
                Some(mut current) => {
                    match current.0.get_child(0) {
                        Some(mut child) => {
                            self.stack.push(current);
                            if child.node_val.is_some() {
                                let tok = child.node_val.unwrap();
                                if tok.tok_type == Type::Oparen {
                                    self.push_whitespace(&mut pretty);
                                    pretty.push('(');
                                    pretty.push('\n');
                                } else if tok.tok_type == Type::OpenList {
                                    self.push_whitespace(&mut pretty);
                                    pretty.push('<');
                                    pretty.push('\n');
                                }
                                child.node_val = Some(tok);
                            }
                            self.stack.push((child, 0));
                        },
                        None => {
                            if current.0.node_val.is_some() {
                                let tok = current.0.node_val.unwrap();
                                self.push_whitespace(&mut pretty);
                                match tok.tok_type {
                                    Type::Oparen => pretty.push(')'),
                                    Type::OpenList => pretty.push('>'),
                                    _ => pretty.push_str(&tok.get_lexed())
                                }
                            }
                            pretty.push('\n');
                        }
                    }
                },
                None => {
                    match self.ast.get_child(0) {
                        Some(mut child) => {
                            if child.node_val.is_some() {
                                let tok = child.node_val.unwrap();
                                if tok.tok_type == Type::Oparen {
                                    self.push_whitespace(&mut pretty);
                                    pretty.push('(');
                                    pretty.push('\n');
                                } else if tok.tok_type == Type::OpenList {
                                    self.push_whitespace(&mut pretty);
                                    pretty.push('<');
                                    pretty.push('\n');
                                }
                                child.node_val = Some(tok);
                            }
                            self.stack.push((child, 0));
                        },
                        None => break
                    }
                }
            }
            if self.stack.is_empty() && self.ast.child_count() == 0 {
                break;
            }
        }
        pretty
    }
}

impl EvalTrait for Eval {
    fn eval(&mut self) {
        let mut scope = Scope::new_root();
        while !self.evaluated {
            scope = self.eval_node(scope); // If scope says evaluate, evaluate.
        }
    }

    fn is_evaluated(&self) -> bool {
        self.evaluated
    }
}

impl Eval {
    pub fn new(ast: Ast) -> Self {
        Eval {
            ast: ast,
            stack: Vec::new(),
            evaluated: false
        }
    }

    pub fn new_option(ast: Option<Ast>) -> Self {
        match ast {
            Some(tree) => Eval {
                ast: tree,
                stack: Vec::new(),
                evaluated: false
            },
            None => panic!()
        }
    }

    fn expand_function(&mut self, scope: &mut Scope) -> bool {
        match self.stack.pop() {
            Some(mut current) => {
                match current.0.is_function() {
                    true => {
                        let unwraped_current = current.0.node_val.unwrap();
                        match scope.find_func(&unwraped_current.get_lexed()) {
                            Some(func) => self.inject_params(func),
                            None => {
                                current.0.node_val = Some(unwraped_current);
                                self.stack.push(current);
                                false
                            }
                        }
                    },
                    false => {
                        self.stack.push(current);
                        false
                    }
                }
            },
            None => false
        }
    }

    fn inject_params(&mut self, func: &Func) -> bool {
        match self.stack.pop() {
            Some(mut current) => {
                let mut current_children = current.0.dump_children();
                let func_children = func.params.clone_children();
                for child in func_children.into_iter() {
                    current.0.push_child(builtins::generate_set_ast(child.node_val.unwrap(), current_children.remove(0)));
                }
                current.0.push_child(func.body.clone());
                self.stack.push(current);
                true
            },
            None => false
        }
    }

    fn eval_node(&mut self, mut scope: Scope) -> Scope {
        match self.stack.pop() {
            Some(mut current) => {
                match current.0.get_child(0) {
                    Some(mut child) => {
                        self.stack.push(current);
                        if child.node_val.is_some() {
                            let tok = child.node_val.unwrap();
                            if tok.tok_type == Type::Func {
                                child.node_val = Some(tok);
                                match self.stack.pop() {
                                    Some(mut parent) => {
                                        parent.0.insert_child(child, 0);
                                        self.stack.push(parent);
                                    },
                                    None => panic!()
                                }
                                if !self.expand_function(&mut scope) {
                                    match self.stack.pop() {
                                        Some(mut parent) => {
                                            match parent.0.get_child(1) {
                                                Some(new_child) => {
                                                    self.stack.push(parent);
                                                    self.stack.push((new_child, 1));
                                                },
                                                None => {
                                                    let result = builtins::evaluate_builtin(parent.0, &mut scope);
                                                    if result.is_push() {
                                                        self.stack.push((result.unwrap_push(), parent.1));
                                                    } else if result.is_error() {
                                                        self.evaluated = true;
                                                    } else if result.is_insert() {
                                                        match self.stack.pop() {
                                                            Some(mut new_parent) => {
                                                                parent.0 = result.unwrap_insert();
                                                                let new_index = parent.1 + 1;
                                                                new_parent.0.insert_child(parent.0, parent.1);
                                                                let new = (new_parent.0.get_child(new_index).unwrap(), new_index);
                                                                self.stack.push(new_parent);
                                                                self.stack.push(new);
                                                            },
                                                            None => self.evaluated = true
                                                        }
                                                    }
                                                }
                                            }
                                        },
                                        None => self.evaluated = true
                                    }
                                }
                            } else if tok.tok_type == Type::Cparen {
                                child.node_val = Some(tok);
                                self.stack.push((child, 0));
                                scope = Scope::new(scope);
                            } else {
                                child.node_val = Some(tok);
                                self.stack.push((child, 0));
                            }
                        } else {
                            self.stack.push((child, 0));
                        }
                    },
                    None => {
                        match self.stack.pop() {
                            Some(mut parent) => {
                                let new_index = current.1 + 1;
                                parent.0.insert_child(current.0, current.1);
                                if parent.0.child_count() > new_index {
                                    let new_child = parent.0.get_child(new_index);
                                    self.stack.push(parent);
                                    self.stack.push((new_child.unwrap(), new_index));
                                } else {
                                    let result = builtins::evaluate_builtin(parent.0, &mut scope);
                                    if result.is_push() {
                                        self.stack.push((result.unwrap_push(), parent.1));
                                    } else if result.is_error() {
                                        self.evaluated = true;
                                    }
                                }
                            },
                            None => self.evaluated = true
                        }
                    }
                }
            },
            None => {
                match self.ast.get_child(0) {
                    Some(mut child) => {
                        if child.node_val.is_some() {
                            let tok = child.node_val.unwrap();
                            if tok.tok_type == Type::Func {
                                child.node_val = Some(tok);
                                match self.stack.pop() {
                                    Some(mut parent) => {
                                        parent.0.insert_child(child, 0);
                                        self.stack.push(parent);
                                    },
                                    None => panic!()
                                }
                                if !self.expand_function(&mut scope) {
                                    match self.stack.pop() {
                                        Some(mut parent) => {
                                            match parent.0.get_child(1) {
                                                Some(new_child) => {
                                                    self.stack.push(parent);
                                                    self.stack.push((new_child, 1));
                                                },
                                                None => {
                                                    let result = builtins::evaluate_builtin(parent.0, &mut scope);
                                                    if result.is_push() {
                                                        self.stack.push((result.unwrap_push(), parent.1));
                                                    } else if result.is_error() {
                                                        self.evaluated = true;
                                                    } else if result.is_insert() {
                                                        match self.stack.pop() {
                                                            Some(mut new_parent) => {
                                                                parent.0 = result.unwrap_insert();
                                                                let new_index = parent.1 + 1;
                                                                new_parent.0.insert_child(parent.0, parent.1);
                                                                let new = (new_parent.0.get_child(new_index).unwrap(), new_index);
                                                                self.stack.push(new_parent);
                                                                self.stack.push(new);
                                                            },
                                                            None => self.evaluated = true
                                                        }
                                                    }
                                                }
                                            }
                                        },
                                        None => self.evaluated = true
                                    }
                                }
                            } else if tok.tok_type == Type::Cparen {
                                child.node_val = Some(tok);
                                self.stack.push((child, 0));
                                scope = Scope::new(scope);
                            } else {
                                child.node_val = Some(tok);
                                self.stack.push((child, 0));
                            }
                        } else {
                            self.stack.push((child, 0));
                        }
                    },
                    None => self.evaluated = true
                }
            }
        }
        if self.stack.is_empty() && self.ast.child_count() == 0 {
            self.evaluated = true;
        }
        scope
    }
}

pub struct Scope {
    pub parent: Option<Box<Scope>>,
    funcs: Vec<Func>,
    pub evaluate_scope: bool
}

impl Scope {
    pub fn new(parent: Scope) -> Self
    {
        Scope {
            parent: Some(Box::new(parent)),
            funcs: Vec::new(),
            evaluate_scope: false
        }
    }

    pub fn new_root() -> Self {
        Scope {
            parent: None,
            funcs: Vec::new(),
            evaluate_scope: false
        }
    }

    pub fn insert_func(&mut self, func: Func) {
        if self.find_func(func.get_name()).is_none() {
            self.insert_func_no_search(func);
        }
    }

    pub fn insert_func_no_search(&mut self, func: Func) {
        let loc = self.funcs.binary_search(&func);
        if loc.is_err() {
            self.funcs.insert(loc.unwrap_err(), func);
        }
    }

    pub fn find_func(&mut self, tok_str: &String) -> Option<&mut Func> {
        let loc = self.funcs.binary_search_by(|func| {
            tok_str.cmp(func.get_name())
        });
        match loc {
            Ok(index) => Some(self.funcs.index_mut(index)),
            _ => {
                match self.parent {
                    Some(ref mut parent) => parent.find_func(tok_str),
                    None => None
                }
            }
        }
    }
}

pub struct Func {
    name: String,
    pub body: Ast,
    pub params: Ast
}

impl Func {
    pub fn new(name: String, body: Ast, params: Ast) -> Self {
        Func {
            name: name,
            body: body,
            params: params
        }
    }

    pub fn get_name(&self) -> &String {
        &self.name
    }

    pub fn reset(&mut self, body: Ast, params: Ast) {
        self.body = body;
        self.params = params;
    }
}

impl Ord for Func {
    fn cmp(&self, other: &Func) -> Ordering {
        self.name.cmp(other.get_name())
    }
}

impl PartialOrd for Func {
    fn partial_cmp(&self, other: &Func) -> Option<Ordering> {
        self.name.partial_cmp(other.get_name())
    }
}

impl Eq for Func { }

impl PartialEq for Func {
    fn eq(&self, other: &Func) -> bool {
        self.name.eq(other.get_name())
    }

    fn ne(&self, other: &Func) -> bool {
        self.name.ne(other.get_name())
    }
}
<commit_msg>update<commit_after>use ast::{Ast, AstTrait};
use token::{TokenTrait, Type};
use builtins;
use std::ops::IndexMut;
use std::cmp::Ordering;

pub struct Eval {
    ast: Ast,
    stack: Vec<(Ast, usize)>,
    evaluated: bool
}

pub trait EvalTrait {
    fn eval(&mut self);
    fn is_evaluated(&self) -> bool;
}

pub trait PrettyPrint {
    fn pretty_print(&mut self) -> String;
    fn push_whitespace(&self, pretty: &mut String);
}

impl PrettyPrint for Eval {
    fn push_whitespace(&self, pretty: &mut String) {
        for _ in 0..self.stack.len() {
            pretty.push('\t');
        }
    }

    fn pretty_print(&mut self) -> String {
        let mut pretty = String::new();
        loop {
            match self.stack.pop() {
                Some(mut current) => {
                    match current.0.get_child(0) {
                        Some(mut child) => {
                            self.stack.push(current);
                            if child.node_val.is_some() {
                                let tok = child.node_val.unwrap();
                                if tok.tok_type == Type::Oparen {
                                    self.push_whitespace(&mut pretty);
                                    pretty.push('(');
                                    pretty.push('\n');
                                } else if tok.tok_type == Type::OpenList {
                                    self.push_whitespace(&mut pretty);
                                    pretty.push('<');
                                    pretty.push('\n');
                                }
                                child.node_val = Some(tok);
                            }
                            self.stack.push((child, 0));
                        },
                        None => {
                            if current.0.node_val.is_some() {
                                let tok = current.0.node_val.unwrap();
                                self.push_whitespace(&mut pretty);
                                match tok.tok_type {
                                    Type::Oparen => pretty.push(')'),
                                    Type::OpenList => pretty.push('>'),
                                    _ => pretty.push_str(&tok.get_lexed())
                                }
                            }
                            pretty.push('\n');
                        }
                    }
                },
                None => {
                    match self.ast.get_child(0) {
                        Some(mut child) => {
                            if child.node_val.is_some() {
                                let tok = child.node_val.unwrap();
                                if tok.tok_type == Type::Oparen {
                                    self.push_whitespace(&mut pretty);
                                    pretty.push('(');
                                    pretty.push('\n');
                                } else if tok.tok_type == Type::OpenList {
                                    self.push_whitespace(&mut pretty);
                                    pretty.push('<');
                                    pretty.push('\n');
                                }
                                child.node_val = Some(tok);
                            }
                            self.stack.push((child, 0));
                        },
                        None => break
                    }
                }
            }
            if self.stack.is_empty() && self.ast.child_count() == 0 {
                break;
            }
        }
        pretty
    }
}

impl EvalTrait for Eval {
    fn eval(&mut self) {
        let mut scope = Scope::new_root();
        while !self.evaluated {
            scope = self.eval_node(scope); // If scope says evaluate, evaluate.
        }
    }

    fn is_evaluated(&self) -> bool {
        self.evaluated
    }
}

impl Eval {
    pub fn new(ast: Ast) -> Self {
        Eval {
            ast: ast,
            stack: Vec::new(),
            evaluated: false
        }
    }

    pub fn new_option(ast: Option<Ast>) -> Self {
        match ast {
            Some(tree) => Eval {
                ast: tree,
                stack: Vec::new(),
                evaluated: false
            },
            None => panic!()
        }
    }

    fn expand_function(&mut self, scope: &mut Scope) -> bool {
        match self.stack.pop() {
            Some(mut current) => {
                match current.0.is_function() {
                    true => {
                        let unwraped_current = current.0.node_val.unwrap();
                        match scope.find_func(&unwraped_current.get_lexed()) {
                            Some(func) => self.inject_params(func),
                            None => {
                                current.0.node_val = Some(unwraped_current);
                                self.stack.push(current);
                                false
                            }
                        }
                    },
                    false => {
                        self.stack.push(current);
                        false
                    }
                }
            },
            None => false
        }
    }

    fn inject_params(&mut self, func: &Func) -> bool {
        match self.stack.pop() {
            Some(mut current) => {
                let mut current_children = current.0.dump_children();
                let func_children = func.params.clone_children();
                for child in func_children.into_iter() {
                    current.0.push_child(builtins::generate_set_ast(child.node_val.unwrap(), current_children.remove(0)));
                }
                current.0.push_child(func.body.clone());
                self.stack.push(current);
                true
            },
            None => false
        }
    }

    fn handle_function(&mut self, scope: &mut Scope) {
        if !self.expand_function(scope) {
            match self.stack.pop() {
                Some(mut parent) => {
                    match parent.0.get_child(1) {
                        Some(new_child) => {
                            self.stack.push(parent);
                            self.stack.push((new_child, 1));
                        },
                        None => {
                            let result = builtins::evaluate_builtin(parent.0, scope);
                            if result.is_push() {
                                self.stack.push((result.unwrap_push(), parent.1));
                            } else if result.is_error() {
                                self.evaluated = true;
                            } else if result.is_insert() {
                                match self.stack.pop() {
                                    Some(mut new_parent) => {
                                        parent.0 = result.unwrap_insert();
                                        let new_index = parent.1 + 1;
                                        new_parent.0.insert_child(parent.0, parent.1);
                                        let new = (new_parent.0.get_child(new_index).unwrap(), new_index);
                                        self.stack.push(new_parent);
                                        self.stack.push(new);
                                    },
                                    None => self.evaluated = true
                                }
                            }
                        }
                    }
                },
                None => self.evaluated = true
            }
        }
    }

    fn eval_node(&mut self, mut scope: Scope) -> Scope {
        match self.stack.pop() {
            Some(mut current) => {
                match current.0.get_child(0) {
                    Some(mut child) => {
                        self.stack.push(current);
                        if child.node_val.is_some() {
                            let tok = child.node_val.unwrap();
                            if tok.tok_type == Type::Func {
                                child.node_val = Some(tok);
                                match self.stack.pop() {
                                    Some(mut parent) => {
                                        parent.0.insert_child(child, 0);
                                        self.stack.push(parent);
                                    },
                                    None => panic!()
                                }
                                self.handle_function(&mut scope);
                            } else if tok.tok_type == Type::Cparen {
                                child.node_val = Some(tok);
                                self.stack.push((child, 0));
                                scope = Scope::new(scope);
                            } else {
                                child.node_val = Some(tok);
                                self.stack.push((child, 0));
                            }
                        } else {
                            self.stack.push((child, 0));
                        }
                    },
                    None => {
                        match self.stack.pop() {
                            Some(mut parent) => {
                                let new_index = current.1 + 1;
                                parent.0.insert_child(current.0, current.1);
                                if parent.0.child_count() > new_index {
                                    let new_child = parent.0.get_child(new_index);
                                    self.stack.push(parent);
                                    self.stack.push((new_child.unwrap(), new_index));
                                } else {
                                    let result = builtins::evaluate_builtin(parent.0, &mut scope);
                                    if result.is_push() {
                                        self.stack.push((result.unwrap_push(), parent.1));
                                    } else if result.is_error() {
                                        self.evaluated = true;
                                    }
                                }
                            },
                            None => self.evaluated = true
                        }
                    }
                }
            },
            None => {
                match self.ast.get_child(0) {
                    Some(mut child) => {
                        if child.node_val.is_some() {
                            let tok = child.node_val.unwrap();
                            if tok.tok_type == Type::Func {
                                child.node_val = Some(tok);
                                match self.stack.pop() {
                                    Some(mut parent) => {
                                        parent.0.insert_child(child, 0);
                                        self.stack.push(parent);
                                    },
                                    None => panic!()
                                }
                                self.handle_function(&mut scope);
                            } else if tok.tok_type == Type::Cparen {
                                child.node_val = Some(tok);
                                self.stack.push((child, 0));
                                scope = Scope::new(scope);
                            } else {
                                child.node_val = Some(tok);
                                self.stack.push((child, 0));
                            }
                        } else {
                            self.stack.push((child, 0));
                        }
                    },
                    None => self.evaluated = true
                }
            }
        }
        if self.stack.is_empty() && self.ast.child_count() == 0 {
            self.evaluated = true;
        }
        scope
    }
}

pub struct Scope {
    pub parent: Option<Box<Scope>>,
    funcs: Vec<Func>,
    pub evaluate_scope: bool
}

impl Scope {
    pub fn new(parent: Scope) -> Self
    {
        Scope {
            parent: Some(Box::new(parent)),
            funcs: Vec::new(),
            evaluate_scope: false
        }
    }

    pub fn new_root() -> Self {
        Scope {
            parent: None,
            funcs: Vec::new(),
            evaluate_scope: false
        }
    }

    pub fn insert_func(&mut self, func: Func) {
        if self.find_func(func.get_name()).is_none() {
            self.insert_func_no_search(func);
        }
    }

    pub fn insert_func_no_search(&mut self, func: Func) {
        let loc = self.funcs.binary_search(&func);
        if loc.is_err() {
            self.funcs.insert(loc.unwrap_err(), func);
        }
    }

    pub fn find_func(&mut self, tok_str: &String) -> Option<&mut Func> {
        let loc = self.funcs.binary_search_by(|func| {
            tok_str.cmp(func.get_name())
        });
        match loc {
            Ok(index) => Some(self.funcs.index_mut(index)),
            _ => {
                match self.parent {
                    Some(ref mut parent) => parent.find_func(tok_str),
                    None => None
                }
            }
        }
    }
}

pub struct Func {
    name: String,
    pub body: Ast,
    pub params: Ast
}

impl Func {
    pub fn new(name: String, body: Ast, params: Ast) -> Self {
        Func {
            name: name,
            body: body,
            params: params
        }
    }

    pub fn get_name(&self) -> &String {
        &self.name
    }

    pub fn reset(&mut self, body: Ast, params: Ast) {
        self.body = body;
        self.params = params;
    }
}

impl Ord for Func {
    fn cmp(&self, other: &Func) -> Ordering {
        self.name.cmp(other.get_name())
    }
}

impl PartialOrd for Func {
    fn partial_cmp(&self, other: &Func) -> Option<Ordering> {
        self.name.partial_cmp(other.get_name())
    }
}

impl Eq for Func { }

impl PartialEq for Func {
    fn eq(&self, other: &Func) -> bool {
        self.name.eq(other.get_name())
    }

    fn ne(&self, other: &Func) -> bool {
        self.name.ne(other.get_name())
    }
}
<|endoftext|>


<commit_before>
use ast::*;
use env::*;

//use ast::Ast;
use parser::Parser;

pub struct Evaler {
    parser: Parser
}

#[allow(dead_code)]
impl Evaler {
    pub fn new() -> Evaler {
        Evaler {
            parser: Parser::new()
        }
    }

    pub fn eval(&mut self, code: String) -> ExprAst {
        let ast = self.parser.load(code);
        self._eval(ast, &mut Env::new())
    }

    fn _eval(&mut self, exp: ExprAst, env: &mut Env) -> ExprAst {
        if exp.is_self() {
            return exp;
        } else if exp.is_symbol() {
            return env.lookup(exp).unwrap();
        } else if exp.is_quote() {
            return exp.cdr().car();
        } else if exp.is_assign() {
            return self._eval_assign(exp, env);
        } else if exp.is_def() {
            return self._eval_def(exp, env);
        } else if exp.is_begin() {
            return self._eval_begin(exp, env);
        } else if exp.is_if() {
            return self._eval_if(exp, env);
        } else if exp.is_and() {
            return self._eval_and(exp, env);
        } else if exp.is_or() {
            return self._eval_or(exp, env);
        } else if exp.is_cond() {
            return self._eval_cond(exp, env);
        } else if exp.is_pair() { //app
            return self._eval_app(exp, env);
        }
        ExprAst::Int(IntNode::new(0))
    }

    fn _eval_assign(&mut self, exp: ExprAst, env: &mut Env) -> ExprAst {
        let var = exp.cdr().car();
        let val = self._eval(exp.cdr().cdr().car(), env);
        env.def_var(var, val);
        return ExprAst::Symbol(SymbolNode::new("OK"));
    }

    fn _eval_def(&mut self, exp: ExprAst, env: &mut Env) -> ExprAst {
        let var = exp.def_var();
        let val = exp.def_val();
        let val = self._eval(val, env);
        env.def_var(var, val);
        return ExprAst::Symbol(SymbolNode::new("OK"));
    }

    fn _eval_if(&mut self, exp: ExprAst, env: &mut Env) -> ExprAst {
        let pred = exp.cdr().car();
        let t_blk = exp.cdr().cdr().car();
        let f_blk = exp.cdr().cdr().cdr();
        let res = self._eval(pred, env);
        if res.is_true() {
            return self._eval(t_blk, env);
        } else {
            if res.is_empty() {
                return ExprAst::Bool(BoolNode::new(false));
            } else {
                return self._eval(f_blk.car(), env);
            }
        }
    }

    fn _eval_and(&mut self, exp: ExprAst, env: &mut Env) -> ExprAst {
        let mut elems = exp.cdr();
        if elems.is_empty() {
            return ExprAst::Bool(BoolNode::new(true));
        }
        loop {
            if elems.is_last() { break; }
            let res = self._eval(elems.car(), env);
            if res.is_false() {
                return ExprAst::Bool(BoolNode::new(false));
            }
            elems = elems.cdr();
        }
        return self._eval(elems.car(), env);
    }

    fn _eval_or(&mut self, exp: ExprAst, env: &mut Env) -> ExprAst {
        let mut elems = exp.cdr();
        if elems.is_empty() {
            return ExprAst::Bool(BoolNode::new(true));
        }
        loop {
            if elems.is_last() { break; }
            let res = self._eval(elems.car(), env);
            if res.is_true() {
                return ExprAst::Bool(BoolNode::new(true));
            }
            elems = elems.cdr();
        }
        return self._eval(elems.car(), env);
    }

    fn _eval_cond(&mut self, exp: ExprAst, env: &mut Env) -> ExprAst {
        let mut elems = exp.cdr().car();
        loop {
            if elems.is_empty() { break; }
            let cur = elems.car();
            let val = self._eval(cur.clone(), env);
            if val.is_true() || val == ExprAst::Symbol(SymbolNode::new("else")) {
                return self._eval(cur.clone().cdr().car(), env);
            }
            elems = elems.cdr();
        }
        return ExprAst::Bool(BoolNode::new(true));
    }

    fn _eval_begin(&mut self, exp: ExprAst, env: &mut Env) -> ExprAst {
        let mut _exp = exp.cdr();
        loop {
            if _exp.is_last() { break; }
            self._eval(_exp.car(), env);
            _exp = _exp.cdr();
        }
        return self._eval(_exp.car(), env);
    }

    fn _eval_values(&mut self, exprs: ExprAst, env: &mut Env) -> ExprAst {
        if exprs.is_empty() {
            return ExprAst::Nil;
        } else {
            let first = self._eval(exprs.car(), env);
            return ExprAst::Pair(PairNode::new(first,
                                               self._eval_values(exprs.cdr(), env)));
        }
    }

    fn _eval_app(&mut self, expr: ExprAst, env: &mut Env) -> ExprAst {
        let _proc = self._eval(expr.car(), env);
        if _proc.is_proc() {
            let _args = self._eval_values(expr.cdr(), env);
            let func = _proc.as_proc().func();
            return func(_args);
        } else {
            return ExprAst::Bool(BoolNode::new(true));
        }
    }

}

#[test]
fn test_evaler() {
    let mut evaler = Evaler::new();
    let res = evaler.eval("11".to_string());
    assert!(res.as_int() == 11);

    let res = evaler.eval(r#""hello""#.to_string());
    assert!(res.as_str() == "hello");

    let res = evaler.eval("#t".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(and #t #t)".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(and #t #f)".to_string());
    assert!(res.as_bool() == false);

    let res = evaler.eval("(or #t #t)".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(or #f #f)".to_string());
    assert!(res.as_bool() == false);

    let res = evaler.eval("(or #t #f)".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(set! a 1)".to_string());
    assert!(res.as_str() == "OK");

    let res = evaler.eval("(integer? 1)".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(boolean? #t)".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(boolean? #f)".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(integer? #t)".to_string());
    assert!(res.as_bool() == false);

    let res = evaler.eval("(+ 1 1)".to_string());
    assert!(res.as_int() == 2);

    let res = evaler.eval("(+ 1 1 1)".to_string());
    assert!(res.as_int() == 3);

    let res = evaler.eval("(+ 1 1 -1 -1)".to_string());
    assert!(res.as_int() == 0);

    let res = evaler.eval("(/ 2 1)".to_string());
    assert!(res.as_int() == 2);

    let res = evaler.eval("(* 2 2)".to_string());
    assert!(res.as_int() == 4);

    let res = evaler.eval("(> 2 1)".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(> 1 2)".to_string());
    assert!(res.as_bool() == false);

    let res = evaler.eval("(> 1 1)".to_string());
    assert!(res.as_bool() == false);

    let res = evaler.eval("(eq? 1 1)".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(eq? 1 2)".to_string());
    assert!(res.as_bool() == false);

    let res = evaler.eval("(eq? 1 #f)".to_string());
    assert!(res.as_bool() == false);

    //let res = evaler.eval("(pair? '())".to_string());
    //assert!(res.as_bool());
}
<commit_msg>cleanup<commit_after>use ast::*;
use env::*;
use parser::*;

pub struct Evaler {
    parser: Parser
}

#[allow(dead_code)]
impl Evaler {
    pub fn new() -> Evaler {
        Evaler {
            parser: Parser::new()
        }
    }

    pub fn eval(&mut self, code: String) -> ExprAst {
        let ast = self.parser.load(code);
        self._eval(ast, &mut Env::new())
    }

    fn _eval(&mut self, exp: ExprAst, env: &mut Env) -> ExprAst {
        if exp.is_self() {
            return exp;
        } else if exp.is_symbol() {
            return env.lookup(exp).unwrap();
        } else if exp.is_quote() {
            return exp.cdr().car();
        } else if exp.is_assign() {
            return self._eval_assign(exp, env);
        } else if exp.is_def() {
            return self._eval_def(exp, env);
        } else if exp.is_begin() {
            return self._eval_begin(exp, env);
        } else if exp.is_if() {
            return self._eval_if(exp, env);
        } else if exp.is_and() {
            return self._eval_and(exp, env);
        } else if exp.is_or() {
            return self._eval_or(exp, env);
        } else if exp.is_cond() {
            return self._eval_cond(exp, env);
        } else if exp.is_pair() { //app
            return self._eval_app(exp, env);
        }
        ExprAst::Int(IntNode::new(0))
    }

    fn _eval_assign(&mut self, exp: ExprAst, env: &mut Env) -> ExprAst {
        let var = exp.cdr().car();
        let val = self._eval(exp.cdr().cdr().car(), env);
        env.def_var(var, val);
        return ExprAst::Symbol(SymbolNode::new("OK"));
    }

    fn _eval_def(&mut self, exp: ExprAst, env: &mut Env) -> ExprAst {
        let var = exp.def_var();
        let val = exp.def_val();
        let val = self._eval(val, env);
        env.def_var(var, val);
        return ExprAst::Symbol(SymbolNode::new("OK"));
    }

    fn _eval_if(&mut self, exp: ExprAst, env: &mut Env) -> ExprAst {
        let pred = exp.cdr().car();
        let t_blk = exp.cdr().cdr().car();
        let f_blk = exp.cdr().cdr().cdr();
        let res = self._eval(pred, env);
        if res.is_true() {
            return self._eval(t_blk, env);
        } else {
            if res.is_empty() {
                return ExprAst::Bool(BoolNode::new(false));
            } else {
                return self._eval(f_blk.car(), env);
            }
        }
    }

    fn _eval_and(&mut self, exp: ExprAst, env: &mut Env) -> ExprAst {
        let mut elems = exp.cdr();
        if elems.is_empty() {
            return ExprAst::Bool(BoolNode::new(true));
        }
        loop {
            if elems.is_last() { break; }
            let res = self._eval(elems.car(), env);
            if res.is_false() {
                return ExprAst::Bool(BoolNode::new(false));
            }
            elems = elems.cdr();
        }
        return self._eval(elems.car(), env);
    }

    fn _eval_or(&mut self, exp: ExprAst, env: &mut Env) -> ExprAst {
        let mut elems = exp.cdr();
        if elems.is_empty() {
            return ExprAst::Bool(BoolNode::new(true));
        }
        loop {
            if elems.is_last() { break; }
            let res = self._eval(elems.car(), env);
            if res.is_true() {
                return ExprAst::Bool(BoolNode::new(true));
            }
            elems = elems.cdr();
        }
        return self._eval(elems.car(), env);
    }

    fn _eval_cond(&mut self, exp: ExprAst, env: &mut Env) -> ExprAst {
        let mut elems = exp.cdr().car();
        loop {
            if elems.is_empty() { break; }
            let cur = elems.car();
            let val = self._eval(cur.clone(), env);
            if val.is_true() || val == ExprAst::Symbol(SymbolNode::new("else")) {
                return self._eval(cur.clone().cdr().car(), env);
            }
            elems = elems.cdr();
        }
        return ExprAst::Bool(BoolNode::new(true));
    }

    fn _eval_begin(&mut self, exp: ExprAst, env: &mut Env) -> ExprAst {
        let mut _exp = exp.cdr();
        loop {
            if _exp.is_last() { break; }
            self._eval(_exp.car(), env);
            _exp = _exp.cdr();
        }
        return self._eval(_exp.car(), env);
    }

    fn _eval_values(&mut self, exprs: ExprAst, env: &mut Env) -> ExprAst {
        if exprs.is_empty() {
            return ExprAst::Nil;
        } else {
            let first = self._eval(exprs.car(), env);
            return ExprAst::Pair(PairNode::new(first,
                                               self._eval_values(exprs.cdr(), env)));
        }
    }

    fn _eval_app(&mut self, expr: ExprAst, env: &mut Env) -> ExprAst {
        let _proc = self._eval(expr.car(), env);
        if _proc.is_proc() {
            let _args = self._eval_values(expr.cdr(), env);
            let func = _proc.as_proc().func();
            return func(_args);
        } else {
            return ExprAst::Bool(BoolNode::new(true));
        }
    }

}

#[test]
fn test_evaler() {
    let mut evaler = Evaler::new();
    let res = evaler.eval("11".to_string());
    assert!(res.as_int() == 11);

    let res = evaler.eval(r#""hello""#.to_string());
    assert!(res.as_str() == "hello");

    let res = evaler.eval("#t".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(and #t #t)".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(and #t #f)".to_string());
    assert!(res.as_bool() == false);

    let res = evaler.eval("(or #t #t)".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(or #f #f)".to_string());
    assert!(res.as_bool() == false);

    let res = evaler.eval("(or #t #f)".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(set! a 1)".to_string());
    assert!(res.as_str() == "OK");

    let res = evaler.eval("(integer? 1)".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(boolean? #t)".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(boolean? #f)".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(integer? #t)".to_string());
    assert!(res.as_bool() == false);

    let res = evaler.eval("(+ 1 1)".to_string());
    assert!(res.as_int() == 2);

    let res = evaler.eval("(+ 1 1 1)".to_string());
    assert!(res.as_int() == 3);

    let res = evaler.eval("(+ 1 1 -1 -1)".to_string());
    assert!(res.as_int() == 0);

    let res = evaler.eval("(/ 2 1)".to_string());
    assert!(res.as_int() == 2);

    let res = evaler.eval("(* 2 2)".to_string());
    assert!(res.as_int() == 4);

    let res = evaler.eval("(> 2 1)".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(> 1 2)".to_string());
    assert!(res.as_bool() == false);

    let res = evaler.eval("(> 1 1)".to_string());
    assert!(res.as_bool() == false);

    let res = evaler.eval("(eq? 1 1)".to_string());
    assert!(res.as_bool());

    let res = evaler.eval("(eq? 1 2)".to_string());
    assert!(res.as_bool() == false);

    let res = evaler.eval("(eq? 1 #f)".to_string());
    assert!(res.as_bool() == false);

    //let res = evaler.eval("(pair? '())".to_string());
    //assert!(res.as_bool());
}
<|endoftext|>


<commit_before>use parser::{parse};
use ast::Expr::*;
use ast::UnOp::*;
use ast::BinOp::*;
use ast::Dec::*;
use ast::*;

fn subst(e: Expr, x: Expr, v: Expr) -> Expr {
  let sub = |e1: Expr| subst(e1.clone(), x.clone(), v.clone());

  match (e.clone(), x.clone()) {
    (Var(ref s1), Var(ref s2)) if s1 == s2 => v.clone(),
    (FnCall(v1, xs), _) => {
      let xs2 = xs.iter().map(|xn| sub(xn.clone())).collect();

      FnCall(Box::new(sub(*v1)), xs2)
    },
    (Var(_), _) => e,
    (Int(_), _) => e,
    (Bool(_), _) => e,
    (Addr(_), _) => e,
    (Bop(op, e1, e2), _) => {
      Bop(
        op,
        Box::new(sub(*e1)),
        Box::new(sub(*e2))
      )
    },
    (Assign(e1, e2, e3), _) => {
      Assign(
        Box::new(sub(*e1)),
        Box::new(sub(*e2)),
        Box::new(sub(*e3))
      )
    },
    (Uop(op, e1), _) => Uop(op, Box::new(sub(*e1))),
    (Ternary(e1, e2, e3), _) => {
      Ternary(
        Box::new(sub(*e1)),
        Box::new(sub(*e2)),
        Box::new(sub(*e3))
      )
    },
    (Decl(d, y, e1, e2), _) => {
      let e2s = if *y == x {
        *e2
      } else {
        sub(*e2)
      };

      Decl(
        d,
        Box::new(*y),
        Box::new(sub(*e1)),
        Box::new(e2s)
      )
    },
    (Func(name, e1, xs), _) => {
      match xs.iter().find(|y| **y == x) {
        Some(_) => e,
        None if name == Some(Box::new(x.clone())) => e,
        None => Func(name, Box::new(sub(*e1)), xs)
      }
    }
  }
}

pub fn step(mut state: State) -> State {
  let st_step = |s: &mut State, e1: &Expr| step(s.with(e1.clone())).expr;

  debug!("step(e) : {:?}", state.expr);
  debug!("step(state) : {:?}", state.mem);
  let e1 = match state.expr.clone() {
    Addr(addr) => {
      state.get(addr)
    },
    /**
     * Values are ineligible for step
     */
    Int(_) | Bool(_) | Func(_, _, _) | Var(_) => {
      debug!("stepping on a value {:?}", state.expr);
      panic!("stepping on a value");
    },
    /**
     * Base cases
     */
    Uop(Not, ref e1) if e1.is_bool() => {
      Bool(!e1.to_bool())
    },
    Uop(Neg, ref e1) if e1.is_int() => {
      Int(-1 * e1.to_int())
    },
    Bop(And, ref e1, ref e2) if e1.is_bool() && e2.is_bool() => {
      Bool(e1.to_bool() && e2.to_bool())
    },
    Bop(Or, ref e1, ref e2) if e1.is_bool() && e2.is_bool() => {
      Bool(e1.to_bool() || e2.to_bool())
    },
    Bop(Eq, ref e1, ref e2) if e1.is_value() && e2.is_value() => {
      Bool(*e1 == *e2)
    },
    Bop(Ne, ref e1, ref e2) if e1.is_value() && e2.is_value() => {
      Bool(*e1 != *e2)
    },
    Bop(Mod, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      let n1 = e1.to_int();
      let n2 = e2.to_int();

      // rust % gives the remainder, not modulus
      let result = ((n1 % n2) + n2) % n2;

      Int(result)
    },
    Bop(Lt, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Bool(e1.to_int() < e2.to_int())
    },
    Bop(Gt, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Bool(e1.to_int() > e2.to_int())
    },
    Bop(Leq, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Bool(e1.to_int() <= e2.to_int())
    },
    Bop(Geq, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Bool(e1.to_int() >= e2.to_int())
    },
    Bop(Plus, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Int(e1.to_int() + e2.to_int())
    },
    Bop(Minus, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Int(e1.to_int() - e2.to_int())
    },
    Bop(Times, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Int(e1.to_int() * e2.to_int())
    },
    Bop(Div, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Int(e1.to_int() / e2.to_int())
    },
    Bop(Seq, ref v1, ref e2) if v1.is_value() => {
      *e2.clone()
    },
    Assign(ref v1, ref v2, ref e3) if v1.is_addr() && v2.is_value() => {
      let addr = v1.to_addr();
      state.assign(addr.clone(), *v2.clone());
      debug!("done assigning {:?}", state.mem);
      *e3.clone()
    },
    Ternary(ref v1, ref e2, ref e3) if v1.is_value() => {
      match v1.to_bool() {
        true => *e2.clone(),
        false => *e3.clone(),
      }
    },
    Decl(ref dconst, ref x, ref v1, ref e2) if *dconst == DConst && v1.is_value() => {
      subst(*e2.clone(), *x.clone(), *v1.clone())
    },
    Decl(ref dvar, ref x, ref v1, ref e2) if *dvar == DVar && v1.is_value() => {
      let addr = state.alloc(*v1.clone());
      subst(*e2.clone(), *x.clone(), Expr::Addr(addr))
    },
    FnCall(ref v1, ref es) if v1.is_func() => {
      match **v1 {
        Func(ref name, ref e1, ref xs) => {
          // sub the params
          let exp = xs.iter().zip(es.iter())
            .fold(*e1.clone(), |exp, (xn, en)| subst(exp, xn.clone(), en.clone()));

          // sub the fn body for named functions
          match *name {
            None => exp,
            Some(ref s) => subst(exp, *s.clone(), *v1.clone())
          }
        },
        _ => {
          debug!("expected a Func, got {:?}", v1);
          panic!()
        },
      }
    },
    /**
     * Search Cases
     */
    Bop(ref op, ref v1, ref e2) if v1.is_value() => {
      Bop(
        op.clone(),
        Box::new(*v1.clone()),
        Box::new(st_step(&mut state, e2))
      )
    },
    Bop(op, e1, e2) => {
      Bop(op, Box::new(st_step(&mut state, &*e1)), e2)
    },
    Assign(ref e1, ref v2, ref e3) if v2.is_value() => {
      Assign(e1.clone(), v2.clone(), Box::new(st_step(&mut state, &*e3)))
    },
    Assign(e1, e2, e3) => {
      Assign(e1, Box::new(st_step(&mut state, &*e2)), e3)
    },
    Uop(op, e1) => {
      Uop(op, Box::new(st_step(&mut state, &*e1)))
    },
    Ternary(e1, e2, e3) => {
      Ternary(Box::new(st_step(&mut state, &*e1)), e2, e3)
    },
    Decl(ref dt, ref addr, ref v1, ref e2) if v1.is_value() => {
      Decl(
        dt.clone(),
        Box::new(*addr.clone()),
        Box::new(*v1.clone()),
        Box::new(st_step(&mut state, e2))
      )
    },
    Decl(dt, addr, e1, e2) => {
      Decl(dt, Box::new(*addr.clone()), Box::new(st_step(&mut state, &*e1)), e2)
    },
    FnCall(ref v1, ref mut args) if v1.is_value() => {
      let mut found_first = true;

      for x in args.iter_mut() {
        if x.is_value() && found_first == true {
          found_first = false;
          *x = st_step(&mut state, x);
        }
      }

      FnCall(Box::new(*v1.clone()), args.clone())
    }
    FnCall(e1, args) => {
      FnCall(Box::new(st_step(&mut state, &*e1)), args)
    }
  };

  debug!("returning with mem {:?}" , state.mem);
  debug!("returning with e {:?}" , state.expr);
  state.with(e1)
}

pub fn boxx(input: &str) -> Expr {
  let mut state = State::from(parse(input));

  let mut num_iterations = 0;

  loop {
    num_iterations += 1;
    if state.expr.is_value() {
      debug!("--- iterations: {}", num_iterations);
      return state.expr
    } else {
      state = step(state)
    }
  }
}
<commit_msg>comment out unused rules<commit_after>use parser::{parse};
use ast::Expr::*;
use ast::UnOp::*;
use ast::BinOp::*;
use ast::Dec::*;
use ast::*;

fn subst(e: Expr, x: Expr, v: Expr) -> Expr {
  let sub = |e1: Expr| subst(e1.clone(), x.clone(), v.clone());

  match (e.clone(), x.clone()) {
    (Var(ref s1), Var(ref s2)) if s1 == s2 => v.clone(),
    (FnCall(v1, xs), _) => {
      let xs2 = xs.iter().map(|xn| sub(xn.clone())).collect();

      FnCall(Box::new(sub(*v1)), xs2)
    },
    (Var(_), _) => e,
    (Int(_), _) => e,
    (Bool(_), _) => e,
    (Addr(_), _) => e,
    (Bop(op, e1, e2), _) => {
      Bop(
        op,
        Box::new(sub(*e1)),
        Box::new(sub(*e2))
      )
    },
    (Assign(e1, e2, e3), _) => {
      Assign(
        Box::new(sub(*e1)),
        Box::new(sub(*e2)),
        Box::new(sub(*e3))
      )
    },
    (Uop(op, e1), _) => Uop(op, Box::new(sub(*e1))),
    (Ternary(e1, e2, e3), _) => {
      Ternary(
        Box::new(sub(*e1)),
        Box::new(sub(*e2)),
        Box::new(sub(*e3))
      )
    },
    (Decl(d, y, e1, e2), _) => {
      let e2s = if *y == x {
        *e2
      } else {
        sub(*e2)
      };

      Decl(
        d,
        Box::new(*y),
        Box::new(sub(*e1)),
        Box::new(e2s)
      )
    },
    (Func(name, e1, xs), _) => {
      match xs.iter().find(|y| **y == x) {
        Some(_) => e,
        None if name == Some(Box::new(x.clone())) => e,
        None => Func(name, Box::new(sub(*e1)), xs)
      }
    }
  }
}

pub fn step(mut state: State) -> State {
  let st_step = |s: &mut State, e1: &Expr| step(s.with(e1.clone())).expr;

  debug!("step(e) : {:?}", state.expr);
  debug!("step(state) : {:?}", state.mem);
  let e1 = match state.expr.clone() {
    Addr(addr) => {
      state.get(addr)
    },
    /**
     * Values are ineligible for step
     */
    Int(_) | Bool(_) | Func(_, _, _) | Var(_) => {
      debug!("stepping on a value {:?}", state.expr);
      panic!("stepping on a value");
    },
    /**
     * Base cases
     */
    Uop(Not, ref e1) if e1.is_bool() => {
      Bool(!e1.to_bool())
    },
    Uop(Neg, ref e1) if e1.is_int() => {
      Int(-1 * e1.to_int())
    },
    Bop(And, ref e1, ref e2) if e1.is_bool() && e2.is_bool() => {
      Bool(e1.to_bool() && e2.to_bool())
    },
    Bop(Or, ref e1, ref e2) if e1.is_bool() && e2.is_bool() => {
      Bool(e1.to_bool() || e2.to_bool())
    },
    Bop(Eq, ref e1, ref e2) if e1.is_value() && e2.is_value() => {
      Bool(*e1 == *e2)
    },
    Bop(Ne, ref e1, ref e2) if e1.is_value() && e2.is_value() => {
      Bool(*e1 != *e2)
    },
    Bop(Mod, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      let n1 = e1.to_int();
      let n2 = e2.to_int();

      // rust % gives the remainder, not modulus
      let result = ((n1 % n2) + n2) % n2;

      Int(result)
    },
    Bop(Lt, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Bool(e1.to_int() < e2.to_int())
    },
    Bop(Gt, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Bool(e1.to_int() > e2.to_int())
    },
    Bop(Leq, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Bool(e1.to_int() <= e2.to_int())
    },
    Bop(Geq, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Bool(e1.to_int() >= e2.to_int())
    },
    Bop(Plus, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Int(e1.to_int() + e2.to_int())
    },
    Bop(Minus, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Int(e1.to_int() - e2.to_int())
    },
    Bop(Times, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Int(e1.to_int() * e2.to_int())
    },
    Bop(Div, ref e1, ref e2) if e1.is_int() && e2.is_int() => {
      Int(e1.to_int() / e2.to_int())
    },
    Bop(Seq, ref v1, ref e2) if v1.is_value() => {
      *e2.clone()
    },
    Assign(ref v1, ref v2, ref e3) if v1.is_addr() && v2.is_value() => {
      let addr = v1.to_addr();
      state.assign(addr.clone(), *v2.clone());
      debug!("done assigning {:?}", state.mem);
      *e3.clone()
    },
    Ternary(ref v1, ref e2, ref e3) if v1.is_value() => {
      match v1.to_bool() {
        true => *e2.clone(),
        false => *e3.clone(),
      }
    },
    Decl(ref dconst, ref x, ref v1, ref e2) if *dconst == DConst && v1.is_value() => {
      subst(*e2.clone(), *x.clone(), *v1.clone())
    },
    Decl(ref dvar, ref x, ref v1, ref e2) if *dvar == DVar && v1.is_value() => {
      let addr = state.alloc(*v1.clone());
      subst(*e2.clone(), *x.clone(), Expr::Addr(addr))
    },
    FnCall(ref v1, ref es) if v1.is_func() => {
      match **v1 {
        Func(ref name, ref e1, ref xs) => {
          // sub the params
          let exp = xs.iter().zip(es.iter())
            .fold(*e1.clone(), |exp, (xn, en)| subst(exp, xn.clone(), en.clone()));

          // sub the fn body for named functions
          match *name {
            None => exp,
            Some(ref s) => subst(exp, *s.clone(), *v1.clone())
          }
        },
        _ => {
          debug!("expected a Func, got {:?}", v1);
          panic!()
        },
      }
    },
    /**
     * Search Cases
     */
    Bop(ref op, ref v1, ref e2) if v1.is_value() => {
      Bop(
        op.clone(),
        Box::new(*v1.clone()),
        Box::new(st_step(&mut state, e2))
      )
    },
    Bop(op, e1, e2) => {
      Bop(op, Box::new(st_step(&mut state, &*e1)), e2)
    },
    /*
     * TODO: should there be a case like this?
    Assign(ref e1, ref v2, ref e3) if v2.is_value() => {
      Assign(e1.clone(), v2.clone(), Box::new(st_step(&mut state, &*e3)))
    },
    */
    Assign(e1, e2, e3) => {
      Assign(e1, Box::new(st_step(&mut state, &*e2)), e3)
    },
    Uop(op, e1) => {
      Uop(op, Box::new(st_step(&mut state, &*e1)))
    },
    Ternary(e1, e2, e3) => {
      Ternary(Box::new(st_step(&mut state, &*e1)), e2, e3)
    },
    /*
     * TODO: should there be a case like this?
    Decl(ref dt, ref addr, ref v1, ref e2) if v1.is_value() => {
      Decl(
        dt.clone(),
        Box::new(*addr.clone()),
        Box::new(*v1.clone()),
        Box::new(st_step(&mut state, e2))
      )
    },
    */
    Decl(dt, addr, e1, e2) => {
      Decl(dt, Box::new(*addr.clone()), Box::new(st_step(&mut state, &*e1)), e2)
    },
    /*
     * TODO: should there be a case like this?
    FnCall(ref v1, ref mut args) if v1.is_value() => {
      let mut found_first = true;

      for x in args.iter_mut() {
        if x.is_value() && found_first == true {
          found_first = false;
          *x = st_step(&mut state, x);
        }
      }

      FnCall(Box::new(*v1.clone()), args.clone())
    }
    */
    FnCall(e1, args) => {
      FnCall(Box::new(st_step(&mut state, &*e1)), args)
    }
  };

  debug!("returning with mem {:?}" , state.mem);
  debug!("returning with e {:?}" , state.expr);
  state.with(e1)
}

pub fn boxx(input: &str) -> Expr {
  let mut state = State::from(parse(input));

  let mut num_iterations = 0;

  loop {
    num_iterations += 1;
    if state.expr.is_value() {
      debug!("--- iterations: {}", num_iterations);
      return state.expr
    } else {
      state = step(state)
    }
  }
}
<|endoftext|>