<commit_before>// (c) 2016 Joost Yervante Damad <joost@productize.be>

use serde::ser;

use Sexp;

use error::{Result, Error};

/// A structure for serializing a Rust value into a symbolic expression.
pub struct Serializer {
    /// the symbolic expression being constructed
    exp: Sexp,
}

impl Serializer {
    fn new() -> Self {
        Serializer {
            exp: Sexp::Empty,
        }
    }

    fn take(self) -> Sexp {
        self.exp
    }
}

impl Default for Serializer {
    fn default() -> Self {
        Serializer::new()
    }
}

impl ser::Serializer for Serializer {
    type Error = Error;
    type SeqState = Vec<Sexp>;
    type TupleState = Vec<Sexp>;
    type TupleStructState = Vec<Sexp>;
    type TupleVariantState = Vec<Sexp>;
    type MapState = ();
    type StructState = Vec<Sexp>;
    type StructVariantState = ();

    fn serialize_bool(&mut self, v: bool) -> Result<()> {
        let b = if v { "true".into() } else { "false".into() };
        self.exp = Sexp::String(b);
        Ok(())
    }

    fn serialize_isize(&mut self, v: isize) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i8(&mut self, v: i8) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i16(&mut self, v: i16) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i32(&mut self, v: i32) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i64(&mut self, v: i64) -> Result<()> {
        self.exp = Sexp::String(format!("{}",v));
        Ok(())
    }

    fn serialize_usize(&mut self, v: usize) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u8(&mut self, v: u8) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u16(&mut self, v: u16) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u32(&mut self, v: u32) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u64(&mut self, v: u64) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_f32(&mut self, v: f32) -> Result<()> {
        self.exp = Sexp::String(v.to_string());
        Ok(())
    }

    fn serialize_f64(&mut self, v: f64) -> Result<()> {
        self.exp = Sexp::String(v.to_string());
        Ok(())
    }

    fn serialize_char(&mut self, v: char) -> Result<()> {
        self.exp = Sexp::String(v.to_string());
        Ok(())
    }

    fn serialize_str(&mut self, v: &str) -> Result<()> {
        self.exp = Sexp::String(v.into());
        Ok(())
    }

    fn serialize_bytes(&mut self, _value: &[u8]) -> Result<()> {
        Err(Error::Encoder("unsupported: &[u8]".into()))
    }

    fn serialize_unit(&mut self) -> Result<()> {
        self.exp = Sexp::Empty;
        Ok(())
    }

    fn serialize_unit_struct(&mut self, _name: &'static str) -> Result<()> {
        self.exp = Sexp::Empty;
        Ok(())
    }

    fn serialize_unit_variant(
        &mut self,
        _name: &str,
        _variant_index: usize,
        variant: &str
    ) -> Result<()> {
        let mut s = String::new();
        s.push_str(variant);
        self.exp = Sexp::String(s.to_lowercase());
        Ok(())
    }

    fn serialize_newtype_struct<T>(
        &mut self,
        name: &'static str,
        value: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        let name:String = name.into();
        let name = name.to_lowercase();
        let mut value = try!(to_sexp(value));
        let mut v = try!(value.take_list());
        let mut v2 = vec![Sexp::String(name)];
        v2.append(&mut v);
        self.exp = Sexp::List(v2);
        Ok(())
    }

    fn serialize_newtype_variant<T>(
        &mut self,
        _name: &str,
        _variant_index: usize,
        variant: &str,
        value: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        let mut s = String::new();
        s.push_str(variant);
        let name = Sexp::String(s.to_lowercase());
        let value = try!(to_sexp(value));
        self.exp = Sexp::List(vec![name, value]);
        Ok(())
    }

    fn serialize_none(&mut self) -> Result<()> {
        self.serialize_unit()
    }

    fn serialize_some<V>(&mut self, value: V) -> Result<()>
        where V: ser::Serialize,
    {
        value.serialize(self)
    }

    fn serialize_seq(&mut self, _len: Option<usize>) -> Result<Vec<Sexp>> {
        Ok(vec![])
    }

    fn serialize_seq_elt<T>(
        &mut self,
        state: &mut Vec<Sexp>,
        elem: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        state.push(try!(to_sexp(elem)));
        Ok(())
    }

    fn serialize_seq_end(&mut self, state: Vec<Sexp>) -> Result<()> {
        self.exp = Sexp::List(state);
        Ok(())
    }

    fn serialize_seq_fixed_size(&mut self, len: usize) -> Result<Vec<Sexp>> {
        self.serialize_seq(Some(len))
    }

    fn serialize_tuple(&mut self, len: usize) -> Result<Vec<Sexp>> {
        self.serialize_seq(Some(len))
    }

    fn serialize_tuple_elt<T>(
        &mut self,
        state: &mut Vec<Sexp>,
        elem: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        self.serialize_seq_elt(state, elem)
    }

    fn serialize_tuple_end(&mut self, state: Vec<Sexp>) -> Result<()> {
        self.serialize_seq_end(state)
    }

    fn serialize_tuple_struct(
        &mut self,
        name: &'static str,
        _len: usize
    ) -> Result<Vec<Sexp>> {
        let mut v = vec![];
        v.push(Sexp::String(name.to_lowercase()));
        Ok(v)
    }

    fn serialize_tuple_struct_elt<V>(
        &mut self,
        state: &mut Vec<Sexp>,
        value: V
    ) -> Result<()>
        where V: ser::Serialize,
    {
        self.serialize_seq_elt(state, value)
    }

    fn serialize_tuple_struct_end(&mut self, state: Vec<Sexp>) -> Result<()> {
        self.serialize_seq_end(state)
    }

    fn serialize_tuple_variant(
        &mut self,
        _enum: &'static str,
        _idx: usize,
        _variant: &'static str,
        _len: usize
    ) -> Result<Vec<Sexp>> {
        Err(Error::Encoder("unsupported: tuple variant".into()))
    }

    fn serialize_tuple_variant_elt<V>(
        &mut self,
        _state: &mut Vec<Sexp>,
        _v: V
    ) -> Result<()>
        where V: ser::Serialize,
    {
        Err(Error::Encoder("unsupported: tuple variant".into()))
    }

    fn serialize_tuple_variant_end(
        &mut self,
        _state: (Vec<Sexp>)
    ) -> Result<()> {
        Err(Error::Encoder("unsupported: tuple variant".into()))
    }

    fn serialize_map(&mut self, _len: Option<usize>) -> Result<()> {
        Err(Error::Encoder("unsupported: map".into()))
    }

    fn serialize_map_key<T>(
        &mut self,
        _state: &mut (),
        _key: T
    ) -> Result<()>
        where T: ser::Serialize
    {
        Err(Error::Encoder("unsupported: map".into()))
    }

    fn serialize_map_value<T>(
        &mut self,
        _state: &mut (),
        _value: T
    ) -> Result<()>
        where T: ser::Serialize
    {
        Err(Error::Encoder("unsupported: map".into()))
    }

    fn serialize_map_end(&mut self, _state: ()) -> Result<()> {
        Err(Error::Encoder("unsupported: map".into()))
    }

    fn serialize_struct(
        &mut self,
        name: &'static str,
        _len: usize
    ) -> Result<Vec<Sexp>> {
        let mut v = vec![];
        let name = name.to_lowercase();
        v.push(Sexp::String(name));
        Ok(v)
    }

    fn serialize_struct_elt<V>(
        &mut self,
        state: &mut Vec<Sexp>,
        key: &'static str,
        value: V
    ) -> Result<()>
        where V: ser::Serialize,
    {
        let mut v = vec![];

        let mut value = to_sexp(value)?;

        // don't add empty values
        if value == Sexp::Empty {
            return Ok(())
        }

        // check if the value is a list that has the same
        // first element name as the containing struct
        // push the elements directly in the containing List
        if value.is_list() {
            let x = value.list()?; // Ok
            println!("x: {:?}", x);
            if !x.is_empty() && x.len() >= 2 {
                if x[0].is_string() {
                    let ok = {
                        let name = x[0].string()?; // Ok
                        key == name.as_str()
                    };
                    if ok {
                        state.push(value.clone()); // TODO optimize
                        return Ok(())
                    }
                }
            }
        }

        v.push(Sexp::String(key.into()));
        // flatten value if appropriate... should only happen for Vec perhaps
        // TODO
        if value.is_list() {
            let x = value.take_list()?;
            for y in &x {
                v.push(y.clone()) // TODO optimize
            }
        } else {
            v.push(value);
        }
        state.push(Sexp::List(v));
        Ok(())
    }

    fn serialize_struct_end(&mut self, state: Vec<Sexp>) -> Result<()> {
        self.serialize_seq_end(state)
    }

    fn serialize_struct_variant(
        &mut self,
        _enum: &'static str,
        _idx: usize,
        _variant: &'static str,
        _len: usize
    ) -> Result<()> {
        Err(Error::Encoder("unsupported: struct variant".into()))
    }

    fn serialize_struct_variant_elt<V>(
        &mut self,
        _state: &mut (),
        _field: &'static str,
        _v: V
    ) -> Result<()>
        where V: ser::Serialize,
    {
        Err(Error::Encoder("unsupported: struct variant".into()))
    }

    fn serialize_struct_variant_end(
        &mut self,
        _state: ()
    ) -> Result<()> {
        Err(Error::Encoder("unsupported: struct variant".into()))
    }
}

/// convert a rust structure to a symbolic expression
pub fn to_sexp<T>(elem: T) -> Result<Sexp>
    where T: ser::Serialize,
{
    let mut ser = Serializer::new();
    try!(elem.serialize(&mut ser));
    Ok(ser.take())
}
<commit_msg>only flatten sequences contained in structs<commit_after>// (c) 2016 Joost Yervante Damad <joost@productize.be>

use serde::ser;

use Sexp;

use error::{Result, Error};

/// A structure for serializing a Rust value into a symbolic expression.
pub struct Serializer {
    /// the symbolic expression being constructed
    exp: Sexp,
    /// indication to the creator of the Serializer that we serialized something from a sequence
    was_seq: bool,
}

impl Serializer {
    fn new() -> Self {
        Serializer {
            exp: Sexp::Empty,
            was_seq: false,
        }
    }

    fn take(self) -> Sexp {
        self.exp
    }
}

impl Default for Serializer {
    fn default() -> Self {
        Serializer::new()
    }
}

impl ser::Serializer for Serializer {
    type Error = Error;
    type SeqState = Vec<Sexp>;
    type TupleState = Vec<Sexp>;
    type TupleStructState = Vec<Sexp>;
    type TupleVariantState = Vec<Sexp>;
    type MapState = ();
    type StructState = Vec<Sexp>;
    type StructVariantState = ();

    fn serialize_bool(&mut self, v: bool) -> Result<()> {
        let b = if v { "true".into() } else { "false".into() };
        self.exp = Sexp::String(b);
        Ok(())
    }

    fn serialize_isize(&mut self, v: isize) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i8(&mut self, v: i8) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i16(&mut self, v: i16) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i32(&mut self, v: i32) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i64(&mut self, v: i64) -> Result<()> {
        self.exp = Sexp::String(format!("{}",v));
        Ok(())
    }

    fn serialize_usize(&mut self, v: usize) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u8(&mut self, v: u8) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u16(&mut self, v: u16) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u32(&mut self, v: u32) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u64(&mut self, v: u64) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_f32(&mut self, v: f32) -> Result<()> {
        self.exp = Sexp::String(v.to_string());
        Ok(())
    }

    fn serialize_f64(&mut self, v: f64) -> Result<()> {
        self.exp = Sexp::String(v.to_string());
        Ok(())
    }

    fn serialize_char(&mut self, v: char) -> Result<()> {
        self.exp = Sexp::String(v.to_string());
        Ok(())
    }

    fn serialize_str(&mut self, v: &str) -> Result<()> {
        self.exp = Sexp::String(v.into());
        Ok(())
    }

    fn serialize_bytes(&mut self, _value: &[u8]) -> Result<()> {
        Err(Error::Encoder("unsupported: &[u8]".into()))
    }

    fn serialize_unit(&mut self) -> Result<()> {
        self.exp = Sexp::Empty;
        Ok(())
    }

    fn serialize_unit_struct(&mut self, _name: &'static str) -> Result<()> {
        self.exp = Sexp::Empty;
        Ok(())
    }

    fn serialize_unit_variant(
        &mut self,
        _name: &str,
        _variant_index: usize,
        variant: &str
    ) -> Result<()> {
        let mut s = String::new();
        s.push_str(variant);
        self.exp = Sexp::String(s.to_lowercase());
        Ok(())
    }

    fn serialize_newtype_struct<T>(
        &mut self,
        name: &'static str,
        value: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        let name:String = name.into();
        let name = name.to_lowercase();
        let mut value = try!(to_sexp(value));
        let mut v = try!(value.take_list());
        let mut v2 = vec![Sexp::String(name)];
        v2.append(&mut v);
        self.exp = Sexp::List(v2);
        Ok(())
    }

    fn serialize_newtype_variant<T>(
        &mut self,
        _name: &str,
        _variant_index: usize,
        variant: &str,
        value: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        let mut s = String::new();
        s.push_str(variant);
        let name = Sexp::String(s.to_lowercase());
        let value = try!(to_sexp(value));
        self.exp = Sexp::List(vec![name, value]);
        Ok(())
    }

    fn serialize_none(&mut self) -> Result<()> {
        self.serialize_unit()
    }

    fn serialize_some<V>(&mut self, value: V) -> Result<()>
        where V: ser::Serialize,
    {
        value.serialize(self)
    }

    fn serialize_seq(&mut self, _len: Option<usize>) -> Result<Vec<Sexp>> {
        self.was_seq = true;
        Ok(vec![])
    }

    fn serialize_seq_elt<T>(
        &mut self,
        state: &mut Vec<Sexp>,
        elem: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        state.push(to_sexp(elem)?);
        Ok(())
    }

    fn serialize_seq_end(&mut self, state: Vec<Sexp>) -> Result<()> {
        self.exp = Sexp::List(state);
        Ok(())
    }

    fn serialize_seq_fixed_size(&mut self, len: usize) -> Result<Vec<Sexp>> {
        self.serialize_seq(Some(len))
    }

    fn serialize_tuple(&mut self, len: usize) -> Result<Vec<Sexp>> {
        self.serialize_seq(Some(len))
    }

    fn serialize_tuple_elt<T>(
        &mut self,
        state: &mut Vec<Sexp>,
        elem: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        self.serialize_seq_elt(state, elem)
    }

    fn serialize_tuple_end(&mut self, state: Vec<Sexp>) -> Result<()> {
        self.serialize_seq_end(state)
    }

    fn serialize_tuple_struct(
        &mut self,
        name: &'static str,
        _len: usize
    ) -> Result<Vec<Sexp>> {
        let mut v = vec![];
        v.push(Sexp::String(name.to_lowercase()));
        Ok(v)
    }

    fn serialize_tuple_struct_elt<V>(
        &mut self,
        state: &mut Vec<Sexp>,
        value: V
    ) -> Result<()>
        where V: ser::Serialize,
    {
        self.serialize_seq_elt(state, value)
    }

    fn serialize_tuple_struct_end(&mut self, state: Vec<Sexp>) -> Result<()> {
        self.serialize_seq_end(state)
    }

    fn serialize_tuple_variant(
        &mut self,
        _enum: &'static str,
        _idx: usize,
        _variant: &'static str,
        _len: usize
    ) -> Result<Vec<Sexp>> {
        Err(Error::Encoder("unsupported: tuple variant".into()))
    }

    fn serialize_tuple_variant_elt<V>(
        &mut self,
        _state: &mut Vec<Sexp>,
        _v: V
    ) -> Result<()>
        where V: ser::Serialize,
    {
        Err(Error::Encoder("unsupported: tuple variant".into()))
    }

    fn serialize_tuple_variant_end(
        &mut self,
        _state: (Vec<Sexp>)
    ) -> Result<()> {
        Err(Error::Encoder("unsupported: tuple variant".into()))
    }

    fn serialize_map(&mut self, _len: Option<usize>) -> Result<()> {
        Err(Error::Encoder("unsupported: map".into()))
    }

    fn serialize_map_key<T>(
        &mut self,
        _state: &mut (),
        _key: T
    ) -> Result<()>
        where T: ser::Serialize
    {
        Err(Error::Encoder("unsupported: map".into()))
    }

    fn serialize_map_value<T>(
        &mut self,
        _state: &mut (),
        _value: T
    ) -> Result<()>
        where T: ser::Serialize
    {
        Err(Error::Encoder("unsupported: map".into()))
    }

    fn serialize_map_end(&mut self, _state: ()) -> Result<()> {
        Err(Error::Encoder("unsupported: map".into()))
    }

    fn serialize_struct(
        &mut self,
        name: &'static str,
        _len: usize
    ) -> Result<Vec<Sexp>> {
        let mut v = vec![];
        let name = name.to_lowercase();
        v.push(Sexp::String(name));
        Ok(v)
    }

    fn serialize_struct_elt<V>(
        &mut self,
        state: &mut Vec<Sexp>,
        key: &'static str,
        value: V
    ) -> Result<()>
        where V: ser::Serialize,
    {
        let mut v = vec![];

        let mut ser = Serializer::new();
        try!(value.serialize(&mut ser));
        let was_seq = ser.was_seq;
        let mut value = ser.take();

        // don't add empty values
        if value == Sexp::Empty {
            return Ok(())
        }

        // check if the value is a list that has the same
        // first element name as the containing struct
        // push the elements directly in the containing List
        if value.is_list() {
            let x = value.list()?; // Ok
            println!("x: {:?}", x);
            if !x.is_empty() && x.len() >= 2 {
                if x[0].is_string() {
                    let ok = {
                        let name = x[0].string()?; // Ok
                        key == name.as_str()
                    };
                    if ok {
                        state.push(value.clone()); // TODO optimize
                        return Ok(())
                    }
                }
            }
        }

        v.push(Sexp::String(key.into()));
        // flatten value if appropriate... should only happen for Vec perhaps
        // TODO
        if was_seq {
            let x = value.take_list()?;
            for y in &x {
                v.push(y.clone()) // TODO optimize
            }
        } else {
            v.push(value);
        }
        state.push(Sexp::List(v));
        Ok(())
    }

    fn serialize_struct_end(&mut self, state: Vec<Sexp>) -> Result<()> {
        self.serialize_seq_end(state)
    }

    fn serialize_struct_variant(
        &mut self,
        _enum: &'static str,
        _idx: usize,
        _variant: &'static str,
        _len: usize
    ) -> Result<()> {
        Err(Error::Encoder("unsupported: struct variant".into()))
    }

    fn serialize_struct_variant_elt<V>(
        &mut self,
        _state: &mut (),
        _field: &'static str,
        _v: V
    ) -> Result<()>
        where V: ser::Serialize,
    {
        Err(Error::Encoder("unsupported: struct variant".into()))
    }

    fn serialize_struct_variant_end(
        &mut self,
        _state: ()
    ) -> Result<()> {
        Err(Error::Encoder("unsupported: struct variant".into()))
    }
}

/// convert a rust structure to a symbolic expression
pub fn to_sexp<T>(elem: T) -> Result<Sexp>
    where T: ser::Serialize,
{
    let mut ser = Serializer::new();
    try!(elem.serialize(&mut ser));
    Ok(ser.take())
}
<|endoftext|>


<commit_before>/*
Module: ptr

Unsafe pointer utility functions
*/
#[abi = "rust-intrinsic"]
native mod rusti {
    fn addr_of<T>(val: T) -> *T;
    fn ptr_offset<T>(ptr: *T, count: ctypes::uintptr_t) -> *T;
    fn memcpy<T>(dst: *T, src: *T, count: ctypes::uintptr_t);
    fn memmove<T>(dst: *T, src: *T, count: ctypes::uintptr_t);
}

/*
Function: addr_of

Get an unsafe pointer to a value
*/
fn addr_of<T>(val: T) -> *T { ret rusti::addr_of(val); }

/*
Function: mut_addr_of

Get an unsafe mutable pointer to a value
*/
fn mut_addr_of<T>(val: T) -> *mutable T unsafe {
    ret unsafe::reinterpret_cast(rusti::addr_of(val));
}

/*
Function: offset

Calculate the offset from a pointer
*/
fn offset<T>(ptr: *T, count: uint) -> *T {
    ret rusti::ptr_offset(ptr, count);
}

/*
Function: mut_offset

Calculate the offset from a mutable pointer
*/
fn mut_offset<T>(ptr: *mutable T, count: uint) -> *mutable T {
    ret rusti::ptr_offset(ptr as *T, count) as *mutable T;
}

/*
Function: null

Create an unsafe null pointer
*/
fn null<T>() -> *T unsafe { ret unsafe::reinterpret_cast(0u); }

/*
Function: memcpy

Copies data from one src to dst that is not overlapping each other.
Count is the number of elements to copy and not the number of bytes.
*/
unsafe fn memcpy<T>(dst: *T, src: *T, count: uint) {
    rusti::memcpy(dst, src, count);
}

/*
Function: memmove

Copies data from one src to dst, overlap between the two pointers may occur.
Count is the number of elements to copy and not the number of bytes.
*/
unsafe fn memmove<T>(dst: *T, src: *T, count: uint)  {
    rusti::memcpy(dst, src, count);
}

#[test]
fn test() unsafe {
    type pair = {mutable fst: int, mutable snd: int};
    let p = {mutable fst: 10, mutable snd: 20};
    let pptr: *mutable pair = mut_addr_of(p);
    let iptr: *mutable int = unsafe::reinterpret_cast(pptr);
    assert (*iptr == 10);;
    *iptr = 30;
    assert (*iptr == 30);
    assert (p.fst == 30);;

    *pptr = {mutable fst: 50, mutable snd: 60};
    assert (*iptr == 50);
    assert (p.fst == 50);
    assert (p.snd == 60);

    let v0 = [32000u16, 32001u16, 32002u16];
    let v1 = [0u16, 0u16, 0u16];

    ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 1u),
                ptr::offset(vec::unsafe::to_ptr(v0), 1u), 1u);
    assert (v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16);
    ptr::memcpy(vec::unsafe::to_ptr(v1),
                ptr::offset(vec::unsafe::to_ptr(v0), 2u), 1u);
    assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16);
    ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 2u),
                vec::unsafe::to_ptr(v0), 1u);
    assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16);
}<commit_msg>fixed memmove. were using memcpy due to copy paste error<commit_after>/*
Module: ptr

Unsafe pointer utility functions
*/
#[abi = "rust-intrinsic"]
native mod rusti {
    fn addr_of<T>(val: T) -> *T;
    fn ptr_offset<T>(ptr: *T, count: ctypes::uintptr_t) -> *T;
    fn memcpy<T>(dst: *T, src: *T, count: ctypes::uintptr_t);
    fn memmove<T>(dst: *T, src: *T, count: ctypes::uintptr_t);
}

/*
Function: addr_of

Get an unsafe pointer to a value
*/
fn addr_of<T>(val: T) -> *T { ret rusti::addr_of(val); }

/*
Function: mut_addr_of

Get an unsafe mutable pointer to a value
*/
fn mut_addr_of<T>(val: T) -> *mutable T unsafe {
    ret unsafe::reinterpret_cast(rusti::addr_of(val));
}

/*
Function: offset

Calculate the offset from a pointer
*/
fn offset<T>(ptr: *T, count: uint) -> *T {
    ret rusti::ptr_offset(ptr, count);
}

/*
Function: mut_offset

Calculate the offset from a mutable pointer
*/
fn mut_offset<T>(ptr: *mutable T, count: uint) -> *mutable T {
    ret rusti::ptr_offset(ptr as *T, count) as *mutable T;
}

/*
Function: null

Create an unsafe null pointer
*/
fn null<T>() -> *T unsafe { ret unsafe::reinterpret_cast(0u); }

/*
Function: memcpy

Copies data from one src to dst that is not overlapping each other.
Count is the number of elements to copy and not the number of bytes.
*/
unsafe fn memcpy<T>(dst: *T, src: *T, count: uint) {
    rusti::memcpy(dst, src, count);
}

/*
Function: memmove

Copies data from one src to dst, overlap between the two pointers may occur.
Count is the number of elements to copy and not the number of bytes.
*/
unsafe fn memmove<T>(dst: *T, src: *T, count: uint)  {
    rusti::memmove(dst, src, count);
}

#[test]
fn test() unsafe {
    type pair = {mutable fst: int, mutable snd: int};
    let p = {mutable fst: 10, mutable snd: 20};
    let pptr: *mutable pair = mut_addr_of(p);
    let iptr: *mutable int = unsafe::reinterpret_cast(pptr);
    assert (*iptr == 10);;
    *iptr = 30;
    assert (*iptr == 30);
    assert (p.fst == 30);;

    *pptr = {mutable fst: 50, mutable snd: 60};
    assert (*iptr == 50);
    assert (p.fst == 50);
    assert (p.snd == 60);

    let v0 = [32000u16, 32001u16, 32002u16];
    let v1 = [0u16, 0u16, 0u16];

    ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 1u),
                ptr::offset(vec::unsafe::to_ptr(v0), 1u), 1u);
    assert (v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16);
    ptr::memcpy(vec::unsafe::to_ptr(v1),
                ptr::offset(vec::unsafe::to_ptr(v0), 2u), 1u);
    assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16);
    ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 2u),
                vec::unsafe::to_ptr(v0), 1u);
    assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16);
}<|endoftext|>


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

#![crate_id = "l20n#0.1-pre"]
#![license = "MPLv2"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]

extern crate serialize;

pub mod compiler;
pub mod data;
pub mod context;
pub mod parser;
<commit_msg>warn mising docs<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! L20n implementation for localization
//!
//! This crate provides an interface to use l20n files to localize your
//! application.

#![crate_id = "l20n#0.1-pre"]
#![license = "MPLv2"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![deny(missing_doc)]

extern crate serialize;

pub mod compiler;
pub mod data;
pub mod context;
pub mod parser;
<|endoftext|>


<commit_before>use libc::{c_int, c_void, c_uint, c_ulonglong};
use ffi::{core, target};
use ffi::execution_engine as engine;
use ffi::execution_engine::*;
use ffi::target_machine::LLVMCodeModel;
use cbox::CBox;
use std::marker::PhantomData;
use std::{mem, ptr};
use std::ops::*;
use compile::Compile;
use context::{Context, GetContext};
use module::Module;
use ty::{StructType, Type};
use util::{self, CastFrom};
use value::{Function, Value};

/// An abstract interface for implementation execution of LLVM modules.
///
/// This is designed to support both interpreter and just-in-time (JIT) compiler implementations.
pub trait ExecutionEngine<'a, 'b:'a> where LLVMExecutionEngineRef:From<&'b Self> {
    /// The options given to the engine upon creation.
    type Options : Copy;

    /// Create a new execution engine with the given `Module` and options, or return a
    /// description of the error.
    fn new(module: &'a Module, options: Self::Options) -> Result<Self, CBox<str>>;

    /// Add a module to the list of modules to interpret or compile.
    fn add_module(&'b self, module: &'a Module) {
        unsafe { engine::LLVMAddModule(self.into(), (&*module).into()) }
    }
    /// Remove a module from the list of modules to interpret or compile.
    fn remove_module(&'b self, module: &'a Module) -> &'a Module {
        unsafe {
            let mut out = mem::uninitialized();
            engine::LLVMRemoveModule(self.into(), module.into(), &mut out, ptr::null_mut());
            out.into()
        }
    }
    /// Execute all of the static constructors for this program.
    fn run_static_constructors(&'b self) {
        unsafe { engine::LLVMRunStaticConstructors(self.into()) }
    }
    /// Execute all of the static destructors for this program.
    fn run_static_destructors(&'b self) {
        unsafe { engine::LLVMRunStaticDestructors(self.into()) }
    }
    /// Attempt to find a function with the name given, or `None` if there wasn't
    /// a function with that name.
    fn find_function(&'b self, name: &str) -> Option<&'a Function> {
        util::with_cstr(name, |c_name| unsafe {
            let mut out = mem::zeroed();
            engine::LLVMFindFunction(self.into(), c_name, &mut out);
            mem::transmute(out)
        })
    }
    /// Run `function` with the arguments given as ``GenericValue`s, then return the result as one.
    ///
    /// Note that if this engine is a `JitEngine`, it only supports a small fraction of combinations
    /// for the arguments and return value, so be warned.
    ///
    /// To convert the arguments to `GenericValue`s, you should use the `GenericValueCast::to_generic` method.
    /// To convert the return value from a `GenericValue`, you should use the `GenericValueCast::from_generic` method.
    fn run_function(&'b self, function: &'a Function, args: &[GenericValue<'a>]) -> GenericValue<'a> {
        let ptr = args.as_ptr() as *mut LLVMGenericValueRef;
        unsafe { engine::LLVMRunFunction(self.into(), function.into(), args.len() as c_uint, ptr).into() }
    }
    /// Returns a pointer to the global value given.
    ///
    /// This is marked as unsafe because the type cannot be guranteed to be the same as the
    /// type of the global value at this point.
    unsafe fn get_global<T>(&'b self, global: &'a Value) -> &'b T {
        mem::transmute(engine::LLVMGetPointerToGlobal(self.into(), global.into()))
    }
    /// Returns a pointer to the global value with the name given.
    ///
    /// This is marked as unsafe because the type cannot be guranteed to be the same as the
    /// type of the global value at this point.
    unsafe fn find_global<T>(&'b self, name: &str) -> Option<&'b T> {
        util::with_cstr(name, |ptr|
            mem::transmute(engine::LLVMGetGlobalValueAddress(self.into(), ptr))
        )
    }

    /// Maps a global to a specific memory location.
    unsafe fn add_global_mapping<T>(&'b self, global: &'a Value, addr: *const T)
    {
      engine::LLVMAddGlobalMapping(self.into(), global.into(), mem::transmute(addr));
    }
}

/// The options to pass to the MCJIT backend.
#[derive(Copy, Clone)]
pub struct JitOptions {
    /// The degree to which optimizations should be done, between 0 and 3.
    ///
    /// 0 represents no optimizations, 3 represents maximum optimization
    pub opt_level: usize
}
/// The MCJIT backend, which compiles functions and values into machine code.
pub struct JitEngine<'a> {
    engine: LLVMExecutionEngineRef,
    marker: PhantomData<&'a ()>
}
native_ref!{contra JitEngine, engine: LLVMExecutionEngineRef}
impl<'a, 'b> JitEngine<'a> {
    /// Run the closure `cb` with the machine code for the function `function`.
    ///
    /// This will check that the types match at runtime when in debug mode, but not release mode.
    /// You should make sure to use debug mode if you want it to error when the types don't match.
    pub fn with_function<C, A, R>(&self, function: &'b Function, cb: C) where A:Compile<'b>, R:Compile<'b>, C:FnOnce(extern fn(A) -> R) {
        if cfg!(not(ndebug)) {
            let ctx = function.get_context();
            let sig = function.get_signature();
            assert_eq!(Type::get::<R>(ctx), sig.get_return());
            let arg = Type::get::<A>(ctx);
            if let Some(args) = StructType::cast(arg) {
                assert_eq!(sig.get_params(), args.get_elements());

            } else {
              let nparams = sig.get_params().len();
              if nparams == 1 {
                assert_eq!(arg, sig.get_params()[0]);
              } else if nparams == 0 {
                assert_eq!(arg, Type::get::<()>(ctx));
              } else {
                panic!("array type arguments are not yet supported; use a tuple or struct instead");
              }
            }
        }
        unsafe {
            cb(self.get_function::<A, R>(function));
        }
    }
    /// Run the closure `cb` with the machine code for the function `function`.
    pub unsafe fn with_function_unchecked<C, A, R>(&self, function: &'b Function, cb: C) where A:Compile<'b>, R:Compile<'b>, C:FnOnce(extern fn(A) -> R) {
        cb(self.get_function::<A, R>(function));
    }
    /// Returns a pointer to the machine code for the function `function`.
    ///
    /// This is marked as unsafe because the types given as arguments and return could be different
    /// from their internal representation.
    pub unsafe fn get_function<A, R>(&self, function: &'b Function) -> extern fn(A) -> R {
        let ptr:&u8 = self.get_global(function);
        mem::transmute(ptr)
    }

    /// Returns a pointer to the machine code for the raw function poionter.
    ///
    /// This is marked as unsafe because the defined function signature and
    /// return could be different from their internal representation.
    pub unsafe fn get_function_raw(&self, function: &'b Function) -> Option<*const ()> {
        let ptr:&u8 = self.get_global(function);
        Some(mem::transmute(ptr))
    }
}
impl<'a, 'b:'a> ExecutionEngine<'a, 'b> for JitEngine<'a> {
    type Options = JitOptions;
    fn new(module: &'a Module, options: JitOptions) -> Result<JitEngine<'a>, CBox<str>> {
        unsafe {
            let mut ee = mem::uninitialized();
            let mut out = mem::zeroed();
            engine::LLVMLinkInMCJIT();
            if target::LLVM_InitializeNativeTarget() == 1 {
                return Err("failed to initialize native target".into())
            }
            if target::LLVM_InitializeNativeAsmPrinter() == 1 {
                return Err("failed to initialize native asm printer".into())
            }
            let mut options = LLVMMCJITCompilerOptions {
                OptLevel: options.opt_level as c_uint,
                CodeModel: LLVMCodeModel::LLVMCodeModelJITDefault,
                NoFramePointerElim: 0,
                EnableFastISel: 1,
                MCJMM: ptr::null_mut()
            };
            let size = mem::size_of::<LLVMMCJITCompilerOptions>();
            let result = engine::LLVMCreateMCJITCompilerForModule(&mut ee, (&*module).into(), &mut options, size as u64, &mut out);
            if result == 0 {
                Ok(ee.into())
            } else {
                Err(CBox::new(out))
            }
        }
    }
}
/// The interpreter backend
pub struct Interpreter<'a> {
    engine: LLVMExecutionEngineRef,
    marker: PhantomData<&'a ()>
}
native_ref!{contra Interpreter, engine: LLVMExecutionEngineRef}
impl<'a> Interpreter<'a> {
    /// Run `function` with the arguments given as ``GenericValue`s, then return the result as one.
    ///
    /// To convert the arguments to `GenericValue`s, you should use the `GenericValueCast::to_generic` method.
    /// To convert the return value from a `GenericValue`, you should use the `GenericValueCast::from_generic` method.
    pub fn run_function(&self, function: &'a Function, args: &[GenericValue<'a>]) -> GenericValue<'a> {
        let ptr = args.as_ptr() as *mut LLVMGenericValueRef;
        unsafe { engine::LLVMRunFunction(self.into(), function.into(), args.len() as c_uint, ptr).into() }
    }
}
impl<'a, 'b:'a> ExecutionEngine<'a, 'b> for Interpreter<'a> {
    type Options = ();
    fn new(module: &'a Module, _: ()) -> Result<Interpreter<'a>, CBox<str>> {
        unsafe {
            let mut ee = mem::uninitialized();
            let mut out = mem::zeroed();
            engine::LLVMLinkInInterpreter();
            let result = engine::LLVMCreateInterpreterForModule(&mut ee, (&*module).into(), &mut out);
            if result == 0 {
                Ok(ee.into())
            } else {
                Err(CBox::new(out))
            }
        }
    }
}
/// A wrapped value that can be passed to an interpreted function or returned from one
pub struct GenericValue<'a> {
    value: LLVMGenericValueRef,
    marker: PhantomData<&'a ()>
}
native_ref!(contra GenericValue, value: LLVMGenericValueRef);
impl<'a> Drop for GenericValue<'a> {
    fn drop(&mut self) {
        unsafe {
            engine::LLVMDisposeGenericValue(self.value)
        }
    }
}

/// A value that can be cast into a `GenericValue` and that a `GenericValue` can be cast into.
///
/// Both these methods require contexts because some `Type` constructors are needed for the
/// conversion and these constructors need a context.
pub trait GenericValueCast<'a> {
    /// Create a `GenericValue` from this value.
    fn to_generic(self, context: &'a Context) -> GenericValue<'a>;
    /// Convert the `GenericValue` into a value of this type again.
    fn from_generic(value: GenericValue<'a>, context: &'a Context) -> Self;
}

impl<'a> GenericValueCast<'a> for f64 {
    fn to_generic(self, ctx: &'a Context) -> GenericValue<'a> {
        unsafe {
            let ty = core::LLVMDoubleTypeInContext(ctx.into());
            engine::LLVMCreateGenericValueOfFloat(ty, self).into()
        }
    }
    fn from_generic(value: GenericValue<'a>, ctx: &'a Context) -> f64 {
        unsafe {
            let ty = core::LLVMDoubleTypeInContext(ctx.into());
            engine::LLVMGenericValueToFloat(ty, value.into())
        }
    }
}
impl<'a> GenericValueCast<'a> for f32 {
    fn to_generic(self, ctx: &'a Context) -> GenericValue<'a> {
        unsafe {
            let ty = core::LLVMFloatTypeInContext(ctx.into());
            engine::LLVMCreateGenericValueOfFloat(ty, self as f64).into()
        }
    }
    fn from_generic(value: GenericValue<'a>, ctx: &'a Context) -> f32 {
        unsafe {
            let ty = core::LLVMFloatTypeInContext(ctx.into());
            engine::LLVMGenericValueToFloat(ty, value.into()) as f32
        }
    }
}
macro_rules! generic_int(
    ($ty:ty, $signed:expr) => (
        impl<'a> GenericValueCast<'a> for $ty {
            fn to_generic(self, ctx: &'a Context) -> GenericValue<'a> {
                unsafe {
                    let ty = <Self as Compile<'a>>::get_type(ctx);
                    engine::LLVMCreateGenericValueOfInt(ty.into(), self as c_ulonglong, $signed as c_int).into()
                }
            }
            fn from_generic(value: GenericValue<'a>, _: &'a Context) -> $ty {
                unsafe {
                    engine::LLVMGenericValueToInt(value.into(), $signed as c_int) as $ty
                }
            }
        }
    );
    (some $signed:ty, $unsigned:ty) => (
        generic_int!{$signed, true}
        generic_int!{$unsigned, false}
    );
);

impl<'a> GenericValueCast<'a> for bool {
    fn to_generic(self, ctx: &'a Context) -> GenericValue<'a> {
        unsafe {
            let ty = <Self as Compile<'a>>::get_type(ctx);
            engine::LLVMCreateGenericValueOfInt(ty.into(), self as c_ulonglong, 0).into()
        }
    }
    fn from_generic(value: GenericValue<'a>, _: &'a Context) -> bool {
        unsafe {
            engine::LLVMGenericValueToInt(value.into(), 0) != 0
        }
    }
}
generic_int!{some i8, u8}
generic_int!{some i16, u16}
generic_int!{some i32, u32}
generic_int!{some i64, u64}
<commit_msg>Reformat engine.rs.<commit_after>use std::marker::PhantomData;
use std::mem;
use std::ptr;
use std::ops::*;

use cbox::CBox;
use ffi::{core, target};
use ffi::execution_engine as engine;
use ffi::execution_engine::*;
use ffi::target_machine::LLVMCodeModel;
use libc::{c_int, c_void, c_uint, c_ulonglong};

use compile::Compile;
use context::{Context, GetContext};
use module::Module;
use ty::{StructType, Type};
use util::{self, CastFrom};
use value::{Function, Value};

/// An abstract interface for implementation execution of LLVM modules.
///
/// This is designed to support both interpreter and just-in-time (JIT) compiler implementations.
pub trait ExecutionEngine<'a, 'b:'a> where LLVMExecutionEngineRef:From<&'b Self>
{
  /// The options given to the engine upon creation.
  type Options : Copy;

  /// Create a new execution engine with the given `Module` and options, or return a
  /// description of the error.
  fn new(module: &'a Module, options: Self::Options) -> Result<Self, CBox<str>>;

  /// Add a module to the list of modules to interpret or compile.
  fn add_module(&'b self, module: &'a Module)
  {
      unsafe { engine::LLVMAddModule(self.into(), (&*module).into()) }
  }

  /// Remove a module from the list of modules to interpret or compile.
  fn remove_module(&'b self, module: &'a Module) -> &'a Module
  {
      unsafe {
          let mut out = mem::uninitialized();
          engine::LLVMRemoveModule(self.into(), module.into(), &mut out, ptr::null_mut());
          out.into()
      }
  }

  /// Execute all of the static constructors for this program.
  fn run_static_constructors(&'b self)
  {
      unsafe { engine::LLVMRunStaticConstructors(self.into()) }
  }

  /// Execute all of the static destructors for this program.
  fn run_static_destructors(&'b self)
  {
      unsafe { engine::LLVMRunStaticDestructors(self.into()) }
  }

  /// Attempt to find a function with the name given, or `None` if there wasn't
  /// a function with that name.
  fn find_function(&'b self, name: &str) -> Option<&'a Function>
  {
      util::with_cstr(name, |c_name| unsafe {
          let mut out = mem::zeroed();
          engine::LLVMFindFunction(self.into(), c_name, &mut out);
          mem::transmute(out)
      })
  }

  /// Run `function` with the arguments given as ``GenericValue`s, then return the result as one.
  ///
  /// Note that if this engine is a `JitEngine`, it only supports a small fraction of combinations
  /// for the arguments and return value, so be warned.
  ///
  /// To convert the arguments to `GenericValue`s, you should use the `GenericValueCast::to_generic` method.
  /// To convert the return value from a `GenericValue`, you should use the `GenericValueCast::from_generic` method.
  fn run_function(&'b self, function: &'a Function, args: &[GenericValue<'a>]) -> GenericValue<'a>
  {
      let ptr = args.as_ptr() as *mut LLVMGenericValueRef;
      unsafe { engine::LLVMRunFunction(self.into(), function.into(), args.len() as c_uint, ptr).into() }
  }

  /// Returns a pointer to the global value given.
  ///
  /// This is marked as unsafe because the type cannot be guranteed to be the same as the
  /// type of the global value at this point.
  unsafe fn get_global<T>(&'b self, global: &'a Value) -> &'b T
  {
      mem::transmute(engine::LLVMGetPointerToGlobal(self.into(), global.into()))
  }

  /// Returns a pointer to the global value with the name given.
  ///
  /// This is marked as unsafe because the type cannot be guranteed to be the same as the
  /// type of the global value at this point.
  unsafe fn find_global<T>(&'b self, name: &str) -> Option<&'b T>
  {
      util::with_cstr(name, |ptr|
          mem::transmute(engine::LLVMGetGlobalValueAddress(self.into(), ptr))
      )
  }

  /// Maps a global to a specific memory location.
  unsafe fn add_global_mapping<T>(&'b self, global: &'a Value, addr: *const T)
  {
    engine::LLVMAddGlobalMapping(self.into(), global.into(), mem::transmute(addr));
  }
}

/// The options to pass to the MCJIT backend.
#[derive(Copy, Clone)]
pub struct JitOptions
{
    /// The degree to which optimizations should be done, between 0 and 3.
    ///
    /// 0 represents no optimizations, 3 represents maximum optimization
    pub opt_level: usize
}

/// The MCJIT backend, which compiles functions and values into machine code.
pub struct JitEngine<'a>
{
    engine: LLVMExecutionEngineRef,
    marker: PhantomData<&'a ()>
}

native_ref!{contra JitEngine, engine: LLVMExecutionEngineRef}

impl<'a, 'b> JitEngine<'a>
{
  /// Run the closure `cb` with the machine code for the function `function`.
  ///
  /// This will check that the types match at runtime when in debug mode, but not release mode.
  /// You should make sure to use debug mode if you want it to error when the types don't match.
  pub fn with_function<C, A, R>(&self, function: &'b Function, cb: C)
  		where A:Compile<'b>, R:Compile<'b>, C:FnOnce(extern fn(A) -> R)
  {
    if cfg!(not(ndebug)) {
     let ctx = function.get_context();
     let sig = function.get_signature();
     assert_eq!(Type::get::<R>(ctx), sig.get_return());
     let arg = Type::get::<A>(ctx);
     if let Some(args) = StructType::cast(arg) {
         assert_eq!(sig.get_params(), args.get_elements());

     } else {
       let nparams = sig.get_params().len();
       if nparams == 1 {
         assert_eq!(arg, sig.get_params()[0]);
       } else if nparams == 0 {
         assert_eq!(arg, Type::get::<()>(ctx));
       } else {
         panic!("array type arguments are not yet supported; use a tuple or struct instead");
       }
     }
    }
    unsafe {
      cb(self.get_function::<A, R>(function));
    }
  }

  /// Run the closure `cb` with the machine code for the function `function`.
  pub unsafe fn with_function_unchecked<C, A, R>(&self, function: &'b Function, cb: C)
  		where A:Compile<'b>, R:Compile<'b>, C:FnOnce(extern fn(A) -> R)
  {
    cb(self.get_function::<A, R>(function));
  }

  /// Returns a pointer to the machine code for the function `function`.
  ///
  /// This is marked as unsafe because the types given as arguments and return could be different
  /// from their internal representation.
  pub unsafe fn get_function<A, R>(&self, function: &'b Function) -> extern fn(A) -> R
  {
    let ptr:&u8 = self.get_global(function);
    mem::transmute(ptr)
  }

  /// Returns a pointer to the machine code for the raw function poionter.
  ///
  /// This is marked as unsafe because the defined function signature and
  /// return could be different from their internal representation.
  pub unsafe fn get_function_raw(&self, function: &'b Function) -> Option<*const ()>
  {
    let ptr:&u8 = self.get_global(function);
    Some(mem::transmute(ptr))
  }
}

impl<'a, 'b:'a> ExecutionEngine<'a, 'b> for JitEngine<'a>
{
  type Options = JitOptions;
  fn new(module: &'a Module, options: JitOptions) -> Result<JitEngine<'a>, CBox<str>>
  {
    unsafe {
      let mut ee = mem::uninitialized();
      let mut out = mem::zeroed();
      engine::LLVMLinkInMCJIT();
      if target::LLVM_InitializeNativeTarget() == 1 {
        return Err("failed to initialize native target".into())
      }
      if target::LLVM_InitializeNativeAsmPrinter() == 1 {
        return Err("failed to initialize native asm printer".into())
      }

      let mut options = LLVMMCJITCompilerOptions {
        OptLevel: options.opt_level as c_uint,
        CodeModel: LLVMCodeModel::LLVMCodeModelJITDefault,
        NoFramePointerElim: 0,
        EnableFastISel: 1,
        MCJMM: ptr::null_mut()
      };

      let size = mem::size_of::<LLVMMCJITCompilerOptions>();
      let result = engine::LLVMCreateMCJITCompilerForModule(&mut ee,
      		                                                 (&*module).into(),
      		                                                 &mut options,
      		                                                 size as u64,
      		                                                 &mut out);
      if result == 0 {
          Ok(ee.into())
      } else {
          Err(CBox::new(out))
      }
    }
  }
}

/// The interpreter backend
pub struct Interpreter<'a>
{
  engine: LLVMExecutionEngineRef,
  marker: PhantomData<&'a ()>
}

native_ref!{contra Interpreter, engine: LLVMExecutionEngineRef}

impl<'a> Interpreter<'a>

  /// Run `function` with the arguments given as ``GenericValue`s,
  /// then return the result as one.
  ///
  /// To convert the arguments to `GenericValue`s, you should use the
  /// `GenericValueCast::to_generic` method. To convert the return value
  /// from a `GenericValue`, you should use the `GenericValueCast::from_generic` method.
  pub fn run_function(&self, function: &'a Function,
  	                  args: &[GenericValue<'a>]) -> GenericValue<'a>
  {
    let ptr = args.as_ptr() as *mut LLVMGenericValueRef;
    unsafe {
    	engine::LLVMRunFunction(self.into(),
    		                      function.into(),
    		                      args.len() as c_uint, ptr)
    }.into()
  }
}

impl<'a, 'b:'a> ExecutionEngine<'a, 'b> for Interpreter<'a>
{
  type Options = ();
  fn new(module: &'a Module, _: ()) -> Result<Interpreter<'a>, CBox<str>>
  {
    unsafe {
      let mut ee = mem::uninitialized();
      let mut out = mem::zeroed();

      engine::LLVMLinkInInterpreter();
      let ret = engine::LLVMCreateInterpreterForModule(&mut ee, (&*module).into(), &mut out);

      if ret == 0 {
          Ok(ee.into())
      } else {
          Err(CBox::new(out))
      }
    }
  }
}

/// A wrapped value that can be passed to an interpreted function or returned from one
pub struct GenericValue<'a>
{
  value: LLVMGenericValueRef,
  marker: PhantomData<&'a ()>
}

native_ref!(contra GenericValue, value: LLVMGenericValueRef);

impl<'a> Drop for GenericValue<'a>
{
  fn drop(&mut self) {
    unsafe {
        engine::LLVMDisposeGenericValue(self.value)
    }
  }
}

/// A value that can be cast into a `GenericValue` and that a `GenericValue` can be cast into.
///
/// Both these methods require contexts because some `Type` constructors are needed for the
/// conversion and these constructors need a context.
pub trait GenericValueCast<'a>
{
  /// Create a `GenericValue` from this value.
  fn to_generic(self, context: &'a Context) -> GenericValue<'a>;
  /// Convert the `GenericValue` into a value of this type again.
  fn from_generic(value: GenericValue<'a>, context: &'a Context) -> Self;
}

impl<'a> GenericValueCast<'a> for f64
{
  fn to_generic(self, ctx: &'a Context) -> GenericValue<'a>
  {
    unsafe {
      let ty = core::LLVMDoubleTypeInContext(ctx.into());
      engine::LLVMCreateGenericValueOfFloat(ty, self).into()
    }
  }

  fn from_generic(value: GenericValue<'a>, ctx: &'a Context) -> f64
  {
    unsafe {
      let ty = core::LLVMDoubleTypeInContext(ctx.into());
      engine::LLVMGenericValueToFloat(ty, value.into())
    }
  }
}

impl<'a> GenericValueCast<'a> for f32
{
  fn to_generic(self, ctx: &'a Context) -> GenericValue<'a>
  {
    unsafe {
        let ty = core::LLVMFloatTypeInContext(ctx.into());
        engine::LLVMCreateGenericValueOfFloat(ty, self as f64).into()
    }
  }

  fn from_generic(value: GenericValue<'a>, ctx: &'a Context) -> f32
  {
    unsafe {
        let ty = core::LLVMFloatTypeInContext(ctx.into());
        engine::LLVMGenericValueToFloat(ty, value.into()) as f32
    }
  }
}

macro_rules! generic_int(
  ($ty:ty, $signed:expr) => (
    impl<'a> GenericValueCast<'a> for $ty {
      fn to_generic(self, ctx: &'a Context) -> GenericValue<'a> {
        unsafe {
          let ty = <Self as Compile<'a>>::get_type(ctx);
          engine::LLVMCreateGenericValueOfInt(ty.into(), self as c_ulonglong, $signed as c_int).into()
        }
      }
      fn from_generic(value: GenericValue<'a>, _: &'a Context) -> $ty {
        unsafe {
          engine::LLVMGenericValueToInt(value.into(), $signed as c_int) as $ty
        }
      }
    }
  );
  (some $signed:ty, $unsigned:ty) => (
      generic_int!{$signed, true}
      generic_int!{$unsigned, false}
  );
);

impl<'a> GenericValueCast<'a> for bool
{
  fn to_generic(self, ctx: &'a Context) -> GenericValue<'a>
  {
    unsafe {
      let ty = <Self as Compile<'a>>::get_type(ctx);
      engine::LLVMCreateGenericValueOfInt(ty.into(), self as c_ulonglong, 0).into()
    }
  }

  fn from_generic(value: GenericValue<'a>, _: &'a Context) -> bool
  {
    unsafe {
      engine::LLVMGenericValueToInt(value.into(), 0) != 0
    }
  }
}

generic_int!{some i8, u8}
generic_int!{some i16, u16}
generic_int!{some i32, u32}
generic_int!{some i64, u64}
<|endoftext|>


<commit_before>/// Errors returned by this library
use error_chain::error_chain;

use std::fmt;
use std::io;
use url::ParseError;

#[cfg(feature = "remote_list")]
use std::net::TcpStream;

#[cfg(feature = "remote_list")]
use native_tls::{Error as TlsError, HandshakeError};

pub type Result<T> = ::std::result::Result<T, Error>;

#[derive(Debug)]
pub struct Error(
    /// The kind of the error.
    pub ErrorKind,
);
impl std::error::Error for Error {}

impl Error {
    pub fn kind(&self) -> &ErrorKind {
        &self.0
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

#[derive(Debug)]
/// The kind of an error.
pub enum ErrorKind {
    Io(::std::io::Error),
    Url(::url::ParseError),
    #[cfg(feature = "remote_list")]
    Tls(::native_tls::Error),
    #[cfg(feature = "remote_list")]
    Handshake(HandshakeError<TcpStream>),
    /// A convenient variant for String.
    Msg(String),
    UnsupportedScheme,
    InvalidList,
    NoHost,
    NoPort,
    InvalidHost,
    InvalidEmail,
    InvalidRule(String),
    InvalidDomain(String),
    Uts46(::idna::Errors),
    #[doc(hidden)]
    __Nonexhaustive {},
}

impl fmt::Display for ErrorKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            ErrorKind::Io(e) => write!(f, "{}", e),
            ErrorKind::Url(e) => write!(f, "{}", e),
            #[cfg(feature = "remote_list")]
            ErrorKind::Tls(e) => write!(f, "{}", e),
            #[cfg(feature = "remote_list")]
            ErrorKind::Handshake(e) => write!(f, "{}", e),
            ErrorKind::Msg(e) => write!(f, "{}", e),
            ErrorKind::UnsupportedScheme => write!(f, "UnsupportedScheme"),
            ErrorKind::InvalidList => write!(f, "InvalidList"),
            ErrorKind::NoHost => write!(f, "NoHost"),
            ErrorKind::NoPort => write!(f, "NoPort"),
            ErrorKind::InvalidHost => write!(f, "InvalidHost"),
            ErrorKind::InvalidEmail => write!(f, "InvalidEmail"),
            ErrorKind::InvalidRule(t) => write!(f, "invalid rule: '{}'", t),
            ErrorKind::InvalidDomain(t) => write!(f, "invalid domain: '{}'", t),
            ErrorKind::Uts46(e) => write!(f, "UTS #46 processing error: '{:?}'", e),
            ErrorKind::__Nonexhaustive {} => write!(f, "__Nonexhaustive"),
        }
    }
}

impl From<ErrorKind> for Error {
    fn from(kind: ErrorKind) -> Self {
        Error(kind)
    }
}

impl From<io::Error> for Error {
    fn from(e: io::Error) -> Self {
        Error(ErrorKind::Io(e))
    }
}

impl From<ParseError> for Error {
    fn from(e: url::ParseError) -> Self {
        Error(ErrorKind::Url(e))
    }
}

#[cfg(feature = "remote_list")]
impl From<TlsError> for Error {
    fn from(e: TlsError) -> Self {
        Error(ErrorKind::Tls(e))
    }
}

#[cfg(feature = "remote_list")]
impl From<HandshakeError<TcpStream>> for Error {
    fn from(e: HandshakeError<TcpStream>) -> Self {
        Error(ErrorKind::Handshake(e))
    }
}<commit_msg>remove obsolete import<commit_after>/// Errors returned by this library

use std::fmt;
use std::io;
use url::ParseError;

#[cfg(feature = "remote_list")]
use std::net::TcpStream;

#[cfg(feature = "remote_list")]
use native_tls::{Error as TlsError, HandshakeError};

pub type Result<T> = ::std::result::Result<T, Error>;

#[derive(Debug)]
pub struct Error(
    /// The kind of the error.
    pub ErrorKind,
);
impl std::error::Error for Error {}

impl Error {
    pub fn kind(&self) -> &ErrorKind {
        &self.0
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

#[derive(Debug)]
/// The kind of an error.
pub enum ErrorKind {
    Io(::std::io::Error),
    Url(::url::ParseError),
    #[cfg(feature = "remote_list")]
    Tls(::native_tls::Error),
    #[cfg(feature = "remote_list")]
    Handshake(HandshakeError<TcpStream>),
    /// A convenient variant for String.
    Msg(String),
    UnsupportedScheme,
    InvalidList,
    NoHost,
    NoPort,
    InvalidHost,
    InvalidEmail,
    InvalidRule(String),
    InvalidDomain(String),
    Uts46(::idna::Errors),
    #[doc(hidden)]
    __Nonexhaustive {},
}

impl fmt::Display for ErrorKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            ErrorKind::Io(e) => write!(f, "{}", e),
            ErrorKind::Url(e) => write!(f, "{}", e),
            #[cfg(feature = "remote_list")]
            ErrorKind::Tls(e) => write!(f, "{}", e),
            #[cfg(feature = "remote_list")]
            ErrorKind::Handshake(e) => write!(f, "{}", e),
            ErrorKind::Msg(e) => write!(f, "{}", e),
            ErrorKind::UnsupportedScheme => write!(f, "UnsupportedScheme"),
            ErrorKind::InvalidList => write!(f, "InvalidList"),
            ErrorKind::NoHost => write!(f, "NoHost"),
            ErrorKind::NoPort => write!(f, "NoPort"),
            ErrorKind::InvalidHost => write!(f, "InvalidHost"),
            ErrorKind::InvalidEmail => write!(f, "InvalidEmail"),
            ErrorKind::InvalidRule(t) => write!(f, "invalid rule: '{}'", t),
            ErrorKind::InvalidDomain(t) => write!(f, "invalid domain: '{}'", t),
            ErrorKind::Uts46(e) => write!(f, "UTS #46 processing error: '{:?}'", e),
            ErrorKind::__Nonexhaustive {} => write!(f, "__Nonexhaustive"),
        }
    }
}

impl From<ErrorKind> for Error {
    fn from(kind: ErrorKind) -> Self {
        Error(kind)
    }
}

impl From<io::Error> for Error {
    fn from(e: io::Error) -> Self {
        Error(ErrorKind::Io(e))
    }
}

impl From<ParseError> for Error {
    fn from(e: url::ParseError) -> Self {
        Error(ErrorKind::Url(e))
    }
}

#[cfg(feature = "remote_list")]
impl From<TlsError> for Error {
    fn from(e: TlsError) -> Self {
        Error(ErrorKind::Tls(e))
    }
}

#[cfg(feature = "remote_list")]
impl From<HandshakeError<TcpStream>> for Error {
    fn from(e: HandshakeError<TcpStream>) -> Self {
        Error(ErrorKind::Handshake(e))
    }
}
<|endoftext|>


<commit_before>//
// Sysinfo
//
// Copyright (c) 2017 Guillaume Gomez
//

use libc::{self, c_char, CTL_NET, NET_RT_IFLIST2, PF_ROUTE, RTM_IFINFO2};
use std::ptr::null_mut;
use sys::ffi;

use NetworkExt;

/// Contains network information.
pub struct NetworkData {
    old_in: u64,
    old_out: u64,
    current_in: u64,
    current_out: u64,
}

impl NetworkExt for NetworkData {
    fn get_income(&self) -> u64 {
        self.current_in - self.old_in
    }

    fn get_outcome(&self) -> u64 {
        self.current_out - self.old_out
    }
}

pub fn new() -> NetworkData {
    NetworkData {
        old_in: 0,
        old_out: 0,
        current_in: 0,
        current_out: 0,
    }
}

pub fn update_network(n: &mut NetworkData) {
    let mib = &mut [CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0];
    let mut len = 0;
    if unsafe { libc::sysctl(mib.as_mut_ptr(), 6, null_mut(), &mut len, null_mut(), 0) } < 0 {
        // TODO: might be nice to put an error in here...
        return
    }
    let mut buf = Vec::with_capacity(len);
    unsafe {
        buf.set_len(len);
        if libc::sysctl(mib.as_mut_ptr(), 6, buf.as_mut_ptr(), &mut len, null_mut(), 0) < 0 {
            // TODO: might be nice to put an error in here...
            return
        }
    }
    let buf = buf.as_ptr() as *const c_char;
    let lim = unsafe { buf.offset(len as isize) };
    let mut next = buf;
    let mut totalibytes = 0u64;
    let mut totalobytes = 0u64;
    while next < lim {
        unsafe {
            let ifm = next as *const libc::if_msghdr;
            next = next.offset((*ifm).ifm_msglen as isize);
            if (*ifm).ifm_type == RTM_IFINFO2 as u8 {
                let if2m: *const ffi::if_msghdr2 = ifm as *const ffi::if_msghdr2;
                totalibytes += (*if2m).ifm_data.ifi_ibytes;
                totalobytes += (*if2m).ifm_data.ifi_obytes;
            }
        }
    }
    n.old_in = n.current_in;
    n.current_in = totalibytes;
    n.old_out = n.current_out;
    n.current_out = totalobytes;
}
<commit_msg>Fix nightly pointer error<commit_after>//
// Sysinfo
//
// Copyright (c) 2017 Guillaume Gomez
//

use libc::{self, c_char, CTL_NET, NET_RT_IFLIST2, PF_ROUTE, RTM_IFINFO2};
use std::ptr::null_mut;
use sys::ffi;

use NetworkExt;

/// Contains network information.
pub struct NetworkData {
    old_in: u64,
    old_out: u64,
    current_in: u64,
    current_out: u64,
}

impl NetworkExt for NetworkData {
    fn get_income(&self) -> u64 {
        self.current_in - self.old_in
    }

    fn get_outcome(&self) -> u64 {
        self.current_out - self.old_out
    }
}

pub fn new() -> NetworkData {
    NetworkData {
        old_in: 0,
        old_out: 0,
        current_in: 0,
        current_out: 0,
    }
}

#[allow(cast_ptr_alignment)]
pub fn update_network(n: &mut NetworkData) {
    let mib = &mut [CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0];
    let mut len = 0;
    if unsafe { libc::sysctl(mib.as_mut_ptr(), 6, null_mut(), &mut len, null_mut(), 0) } < 0 {
        // TODO: might be nice to put an error in here...
        return
    }
    let mut buf = Vec::with_capacity(len);
    unsafe {
        buf.set_len(len);
        if libc::sysctl(mib.as_mut_ptr(), 6, buf.as_mut_ptr(), &mut len, null_mut(), 0) < 0 {
            // TODO: might be nice to put an error in here...
            return
        }
    }
    let buf = buf.as_ptr() as *const c_char;
    let lim = unsafe { buf.offset(len as isize) };
    let mut next = buf;
    let mut totalibytes = 0u64;
    let mut totalobytes = 0u64;
    while next < lim {
        unsafe {
            let ifm = next as *const libc::if_msghdr;
            next = next.offset((*ifm).ifm_msglen as isize);
            if (*ifm).ifm_type == RTM_IFINFO2 as u8 {
                let if2m: *const ffi::if_msghdr2 = ifm as *const ffi::if_msghdr2;
                totalibytes += (*if2m).ifm_data.ifi_ibytes;
                totalobytes += (*if2m).ifm_data.ifi_obytes;
            }
        }
    }
    n.old_in = n.current_in;
    n.current_in = totalibytes;
    n.old_out = n.current_out;
    n.current_out = totalobytes;
}
<|endoftext|>


<commit_before>use acyclic_network::{Network, NodeType, NodeIndex};
use weight::{Weight, WeightRange, WeightPerturbanceMethod};
use prob::Prob;
use rand::Rng;

/// Genome representing a feed-forward (acyclic) network with node type `NT`.
#[derive(Clone, Debug)]
pub struct Genome<NT: NodeType> {
    /// Represents the acyclic feed forward network, with `NT` as node type and `Weight` for the edge weights.
    /// Other than that, nodes and edges do not have any further associated information (`()`).
    network: Network<NT, Weight, ()>,

    /// The genome can contain some nodes which cannot be modified or removed. These are the first
    /// `protected_nodes` in `network`.
    protected_nodes: usize,
}

impl<NT: NodeType> Genome<NT> {
    pub fn new() -> Self {
        Genome {
            network: Network::new(),
            protected_nodes: 0,
        }
    }

    pub fn protect_nodes(&mut self) {
        self.protected_nodes = self.network.node_count();
    }

    /// Returns a reference to the feed forward network.

    pub fn network(&self) -> &Network<NT, Weight, ()> {
        &self.network
    }

    /// Connects two previously unconnected nodes by adding a link between `source_node` and `target_node` using `weight`.
    ///
    /// Does not check for cycles. Test for cycles before using this method!
    ///
    /// # Panics
    ///
    /// If one of `source_node` or `target_node` does not exist.
    ///
    /// If a connection between these nodes already exists!
    ///
    /// # Complexity
    ///
    /// O(1) because we use `add_link_unorderd`.

    pub fn add_link(&mut self, source_node: NodeIndex, target_node: NodeIndex, weight: Weight) {
        debug_assert!(!self.network.link_would_cycle(source_node, target_node));
        debug_assert!(self.network.valid_link(source_node, target_node).is_ok());

        let _link_index = self.network.add_link_unordered(source_node, target_node, weight, ());
    }

    pub fn add_node(&mut self, node_type: NT) -> NodeIndex {
        self.network.add_node(node_type, ())
    }

    pub fn node_count(&self) -> usize {
        self.network.node_count()
    }

    fn random_node<R>(&self, tournament_k: usize, rng: &mut R) -> Option<NodeIndex>
        where R: Rng
    {
        assert!(tournament_k > 0);

        let n = self.network.node_count();
        if self.protected_nodes >= n {
            return None;
        }

        let mut min_node = NodeIndex::new(rng.gen_range(self.protected_nodes, n));
        let mut min_degree = self.network.node(min_node).degree();
        for _ in 1..tournament_k {
            let node_idx = NodeIndex::new(rng.gen_range(self.protected_nodes, n));
            let degree = self.network.node(node_idx).degree();
            if degree < min_degree {
                min_node = node_idx;
                min_degree = degree;
            }
        }

        Some(min_node)
    }

    /// Structural Mutation `AddNode`.
    ///
    /// Choose a random link and split it into two by inserting a new node in the middle.
    ///
    /// Note that the new `node_type` should allow incoming and outgoing links! Otherwise
    /// this panics!

    pub fn mutate_add_node<R>(&mut self,
                              node_type: NT,
                              second_link_weight: Option<Weight>,
                              rng: &mut R)
                              -> bool
        where R: Rng
    {
        let link_index = match self.network.random_link_index(rng) {
            Some(idx) => idx,
            None => return false,
        };

        let (orig_source_node, orig_target_node, orig_weight) = {
            let link = self.network.link(link_index);
            (link.source_node_index(),
             link.target_node_index(),
             link.weight())
        };

        // remove original link
        self.network.remove_link_at(link_index);

        // Add new "middle" node
        let middle_node = self.network.add_node(node_type, ());

        // Add two new links connecting the three nodes. This cannot add a cycle!
        //
        // The first link reuses the same weight as the original link.
        // The second link uses `second_link_weight` as weight (or if `None`, `orig_weight`).
        // Ideally this is of full strength as we want to make the modification
        // to the network (CPPN) as little as possible.

        self.add_link(orig_source_node, middle_node, orig_weight);
        self.add_link(middle_node,
                      orig_target_node,
                      second_link_weight.unwrap_or(orig_weight));

        return true;
    }

    /// Structural Mutation `DropNode`.
    ///
    /// Choose a random node and remove it. All in and outgoing links to and from that node
    /// are removed as well. Note that the first `protected_nodes` cannot be removed!
    ///
    /// We choose `tournament_k` random nodes and remove the one with the smallest degree.

    pub fn mutate_drop_node<R>(&mut self, tournament_k: usize, rng: &mut R) -> bool
        where R: Rng
    {
        match self.random_node(tournament_k, rng) {
            None => false,
            Some(node_idx) => {
                self.network.remove_node(node_idx);
                true
            }
        }
    }

    /// Structural Mutation `ModifyNode`.
    ///
    /// Choose a random node and change it's type to `new_node_type`.
    /// Note that protected nodes are not modified.
    ///
    /// We choose from `tournament_k` nodes the one with the smallest degree.

    pub fn mutate_modify_node<R>(&mut self,
                                 new_node_type: NT,
                                 tournament_k: usize,
                                 rng: &mut R)
                                 -> bool
        where R: Rng
    {
        match self.random_node(tournament_k, rng) {
            None => false,
            Some(node_idx) => {
                self.network.node_mut(node_idx).set_node_type(new_node_type);
                true
            }
        }
    }

    /// Structural Mutation `Connect`.
    ///
    /// Mutate the genome by adding a random valid link which does not introduce a cycle.
    ///
    /// Return `true` if the genome was modified. Otherwise `false`.

    pub fn mutate_connect<R>(&mut self, link_weight: Weight, rng: &mut R) -> bool
        where R: Rng
    {
        match self.network.find_random_unconnected_link_no_cycle(rng) {
            Some((source_node, target_node)) => {
                // Add new link to the genome
                self.add_link(source_node, target_node, link_weight);
                return true;
            }
            None => {
                return false;
            }
        }
    }

    /// Structural Mutation `Disconnect`.
    ///
    /// Mutate the genome by removing a random link.
    ///
    /// Return `true` if the genome was modified. Otherwise `false`.

    pub fn mutate_disconnect<R>(&mut self, rng: &mut R) -> bool
        where R: Rng
    {
        match self.network.random_link_index(rng) {
            Some(idx) => {
                self.network.remove_link_at(idx);
                true
            }
            None => false,
        }
    }

    /// Uniformly modify the weight of links, each with a probability of `mutate_element_prob`. It
    /// the genome contains at least one link, it is guaranteed that this method makes a modification.
    ///
    /// Returns the number of modifications (if negative, indicates that we used a random link).

    pub fn mutate_weights<R>(&mut self,
                             mutate_element_prob: Prob,
                             weight_perturbance: &WeightPerturbanceMethod,
                             link_weight_range: &WeightRange,
                             rng: &mut R)
                             -> isize
        where R: Rng
    {
        let mut modifications = 0;

        self.network.each_link_mut(|link| {
            if mutate_element_prob.flip(rng) {
                let new_weight = weight_perturbance.perturb(link.weight(), link_weight_range, rng);
                link.set_weight(new_weight);
                modifications += 1;
            }
        });

        if modifications == 0 {
            // Make at least one change to a randomly selected link.
            if let Some(link_idx) = self.network.random_link_index(rng) {
                let link = self.network.link_mut(link_idx);
                let new_weight = weight_perturbance.perturb(link.weight(), link_weight_range, rng);
                link.set_weight(new_weight);
                modifications -= 1;
            }
        }

        return modifications;
    }
}
<commit_msg>Add crossover_weights(). Unimplemented yet<commit_after>use acyclic_network::{Network, NodeType, NodeIndex};
use weight::{Weight, WeightRange, WeightPerturbanceMethod};
use prob::Prob;
use rand::Rng;

/// Genome representing a feed-forward (acyclic) network with node type `NT`.
#[derive(Clone, Debug)]
pub struct Genome<NT: NodeType> {
    /// Represents the acyclic feed forward network, with `NT` as node type and `Weight` for the edge weights.
    /// Other than that, nodes and edges do not have any further associated information (`()`).
    network: Network<NT, Weight, ()>,

    /// The genome can contain some nodes which cannot be modified or removed. These are the first
    /// `protected_nodes` in `network`.
    protected_nodes: usize,
}

impl<NT: NodeType> Genome<NT> {
    pub fn new() -> Self {
        Genome {
            network: Network::new(),
            protected_nodes: 0,
        }
    }

    pub fn protect_nodes(&mut self) {
        self.protected_nodes = self.network.node_count();
    }

    /// Returns a reference to the feed forward network.

    pub fn network(&self) -> &Network<NT, Weight, ()> {
        &self.network
    }

    /// Connects two previously unconnected nodes by adding a link between `source_node` and `target_node` using `weight`.
    ///
    /// Does not check for cycles. Test for cycles before using this method!
    ///
    /// # Panics
    ///
    /// If one of `source_node` or `target_node` does not exist.
    ///
    /// If a connection between these nodes already exists!
    ///
    /// # Complexity
    ///
    /// O(1) because we use `add_link_unorderd`.

    pub fn add_link(&mut self, source_node: NodeIndex, target_node: NodeIndex, weight: Weight) {
        debug_assert!(!self.network.link_would_cycle(source_node, target_node));
        debug_assert!(self.network.valid_link(source_node, target_node).is_ok());

        let _link_index = self.network.add_link_unordered(source_node, target_node, weight, ());
    }

    pub fn add_node(&mut self, node_type: NT) -> NodeIndex {
        self.network.add_node(node_type, ())
    }

    pub fn node_count(&self) -> usize {
        self.network.node_count()
    }

    fn random_node<R>(&self, tournament_k: usize, rng: &mut R) -> Option<NodeIndex>
        where R: Rng
    {
        assert!(tournament_k > 0);

        let n = self.network.node_count();
        if self.protected_nodes >= n {
            return None;
        }

        let mut min_node = NodeIndex::new(rng.gen_range(self.protected_nodes, n));
        let mut min_degree = self.network.node(min_node).degree();
        for _ in 1..tournament_k {
            let node_idx = NodeIndex::new(rng.gen_range(self.protected_nodes, n));
            let degree = self.network.node(node_idx).degree();
            if degree < min_degree {
                min_node = node_idx;
                min_degree = degree;
            }
        }

        Some(min_node)
    }

    /// Structural Mutation `AddNode`.
    ///
    /// Choose a random link and split it into two by inserting a new node in the middle.
    ///
    /// Note that the new `node_type` should allow incoming and outgoing links! Otherwise
    /// this panics!

    pub fn mutate_add_node<R>(&mut self,
                              node_type: NT,
                              second_link_weight: Option<Weight>,
                              rng: &mut R)
                              -> bool
        where R: Rng
    {
        let link_index = match self.network.random_link_index(rng) {
            Some(idx) => idx,
            None => return false,
        };

        let (orig_source_node, orig_target_node, orig_weight) = {
            let link = self.network.link(link_index);
            (link.source_node_index(),
             link.target_node_index(),
             link.weight())
        };

        // remove original link
        self.network.remove_link_at(link_index);

        // Add new "middle" node
        let middle_node = self.network.add_node(node_type, ());

        // Add two new links connecting the three nodes. This cannot add a cycle!
        //
        // The first link reuses the same weight as the original link.
        // The second link uses `second_link_weight` as weight (or if `None`, `orig_weight`).
        // Ideally this is of full strength as we want to make the modification
        // to the network (CPPN) as little as possible.

        self.add_link(orig_source_node, middle_node, orig_weight);
        self.add_link(middle_node,
                      orig_target_node,
                      second_link_weight.unwrap_or(orig_weight));

        return true;
    }

    /// Structural Mutation `DropNode`.
    ///
    /// Choose a random node and remove it. All in and outgoing links to and from that node
    /// are removed as well. Note that the first `protected_nodes` cannot be removed!
    ///
    /// We choose `tournament_k` random nodes and remove the one with the smallest degree.

    pub fn mutate_drop_node<R>(&mut self, tournament_k: usize, rng: &mut R) -> bool
        where R: Rng
    {
        match self.random_node(tournament_k, rng) {
            None => false,
            Some(node_idx) => {
                self.network.remove_node(node_idx);
                true
            }
        }
    }

    /// Structural Mutation `ModifyNode`.
    ///
    /// Choose a random node and change it's type to `new_node_type`.
    /// Note that protected nodes are not modified.
    ///
    /// We choose from `tournament_k` nodes the one with the smallest degree.

    pub fn mutate_modify_node<R>(&mut self,
                                 new_node_type: NT,
                                 tournament_k: usize,
                                 rng: &mut R)
                                 -> bool
        where R: Rng
    {
        match self.random_node(tournament_k, rng) {
            None => false,
            Some(node_idx) => {
                self.network.node_mut(node_idx).set_node_type(new_node_type);
                true
            }
        }
    }

    /// Structural Mutation `Connect`.
    ///
    /// Mutate the genome by adding a random valid link which does not introduce a cycle.
    ///
    /// Return `true` if the genome was modified. Otherwise `false`.

    pub fn mutate_connect<R>(&mut self, link_weight: Weight, rng: &mut R) -> bool
        where R: Rng
    {
        match self.network.find_random_unconnected_link_no_cycle(rng) {
            Some((source_node, target_node)) => {
                // Add new link to the genome
                self.add_link(source_node, target_node, link_weight);
                return true;
            }
            None => {
                return false;
            }
        }
    }

    /// Structural Mutation `Disconnect`.
    ///
    /// Mutate the genome by removing a random link.
    ///
    /// Return `true` if the genome was modified. Otherwise `false`.

    pub fn mutate_disconnect<R>(&mut self, rng: &mut R) -> bool
        where R: Rng
    {
        match self.network.random_link_index(rng) {
            Some(idx) => {
                self.network.remove_link_at(idx);
                true
            }
            None => false,
        }
    }

    /// Uniformly modify the weight of links, each with a probability of `mutate_element_prob`. It
    /// the genome contains at least one link, it is guaranteed that this method makes a modification.
    ///
    /// Returns the number of modifications (if negative, indicates that we used a random link).

    pub fn mutate_weights<R>(&mut self,
                             mutate_element_prob: Prob,
                             weight_perturbance: &WeightPerturbanceMethod,
                             link_weight_range: &WeightRange,
                             rng: &mut R)
                             -> isize
        where R: Rng
    {
        let mut modifications = 0;

        self.network.each_link_mut(|link| {
            if mutate_element_prob.flip(rng) {
                let new_weight = weight_perturbance.perturb(link.weight(), link_weight_range, rng);
                link.set_weight(new_weight);
                modifications += 1;
            }
        });

        if modifications == 0 {
            // Make at least one change to a randomly selected link.
            if let Some(link_idx) = self.network.random_link_index(rng) {
                let link = self.network.link_mut(link_idx);
                let new_weight = weight_perturbance.perturb(link.weight(), link_weight_range, rng);
                link.set_weight(new_weight);
                modifications -= 1;
            }
        }

        return modifications;
    }

    pub fn crossover_weights<R>(&mut self, _partner: &Self, _rng: &mut R) -> isize
        where R: Rng
    {
        unimplemented!()
    }
}
<|endoftext|>


<commit_before>
use std::io::Read;  // Trait providing read_to_string()

use hyper;
use rustc_serialize;

use projects;
use groups;

pub const API_VERSION: u16 = 3;

#[derive(Debug, RustcDecodable, RustcEncodable)]
pub struct Version {
    pub version: String,
    pub revision: String,
}

#[derive(Debug)]
pub struct Pagination {
    pub page: u16,
    pub per_page: u16,
}

#[derive(Debug)]
pub struct GitLab {
    scheme: String,
    domain: String,
    port: u16,
    private_token: String,
    client: hyper::Client,
    pagination: Pagination,
}

impl GitLab {

    pub fn new(scheme: &str, domain: &str, port: u16, private_token: &str) -> GitLab {
        GitLab {
            scheme: scheme.to_string(),
            domain: domain.to_string(),
            port:   port,
            private_token: private_token.to_string(),
            client: hyper::Client::new(),
            pagination: Pagination {page: 1, per_page: 20},
        }
    }

    pub fn new_http(domain: &str, private_token: &str) -> GitLab {
        GitLab::new("http", &domain, 80, &private_token)
    }

    pub fn new_https(domain: &str, private_token: &str) -> GitLab {
        GitLab::new("https", &domain, 443, &private_token)
    }

    pub fn build_url(&self, command: &str) -> String {
        format!("{}://{}:{}/api/v{}/{}?private_token={}&page={}&per_page={}",
                                self.scheme,
                                self.domain,
                                self.port,
                                API_VERSION,
                                command,
                                self.private_token,
                                self.pagination.page,
                                self.pagination.per_page)
    }

    pub fn attempt_connection(&self) -> Result<hyper::client::Response, hyper::Error> {
        // self.get("version")
        let url = self.build_url("version");
        // Close connections after each GET.
        let res = self.client.get(&url).header(hyper::header::Connection::close()).send();

        res
    }

    pub fn set_pagination(&mut self, pagination: Pagination) {
        self.pagination = pagination;
    }

    pub fn get<T>(&self, command: &str) -> Result<T, rustc_serialize::json::DecoderError>
            where T: rustc_serialize::Decodable {

        let url = self.build_url(command);
        let mut res: hyper::client::Response =
                        self.client
                        .get(&url)
                        .header(hyper::header::Connection::close())
                        .send()
                        .unwrap();

        let mut body = String::new();
        res.read_to_string(&mut body).unwrap();

        rustc_serialize::json::decode(body.as_str())
    }

    pub fn version(&self) -> Result<Version, rustc_serialize::json::DecoderError> {
        self.get("version")
    }

    pub fn groups(&self) -> Result<groups::Groups, rustc_serialize::json::DecoderError> {
        self.get("groups")
    }

    pub fn projects(&self) {
        // let mut res: hyper::client::Response = self.get("projects").unwrap();
        let url = self.build_url("projects");
        let mut res: hyper::client::Response =
                        self.client
                        .get(&url)
                        .header(hyper::header::Connection::close())
                        .send()
                        .unwrap();
        println!("####################################################################");
        println!("res: {:?}", res);
        println!("####################################################################");
        println!("Response: {}", res.status);
        println!("####################################################################");
        println!("Headers:\n{}", res.headers);
        println!("####################################################################");

        // let fresh_request = Request::get(url);
        // let streaming_request = fresh_request.start();
        // let mut response = streaming_request.send();
        // Ok(response.read_to_string())

        // let mut body = Vec::new::<u8>();
        // body.resize(, 0);
        // let result = res.read_exact(&body);

        // println!("####################################################################");
        println!("----------------------------");
        let mut body = String::new();
        println!("----------------------------");
        res.read_to_string(&mut body).unwrap();
        // println!("####################################################################");
        // let result = res.read_to_string(&mut body);
        // println!("####################################################################");
        // println!("body:\n{}", body);

        let projects: projects::Projects = rustc_serialize::json::decode(body.as_str()).unwrap();
        println!("{}", projects.p[0].description);

    }

    // pub fn projects(&self) -> ProjectManager {
    //     ProjectManager()
    // }
}

#[cfg(test)]
mod tests {
    use std::env;
    use gitlab::GitLab;

    #[test]
    fn list_projects() {
        let token = match env::var("GITLAB_TOKEN") {
            Ok(val) => val,
            Err(_)  => panic!("Please set environment variable 'GITLAB_TOKEN'"),
        };

        let gl = GitLab::new_https("gitlab.com", &token);
        println!("gl: {:?}", gl);

        gl.projects();
        // assert_eq!(gl.attempt_connection().unwrap().status, hyper::Ok);

    }
}
<commit_msg>Add a list_group() test<commit_after>
use std::io::Read;  // Trait providing read_to_string()

use hyper;
use rustc_serialize;

use projects;
use groups;

pub const API_VERSION: u16 = 3;

#[derive(Debug, RustcDecodable, RustcEncodable)]
pub struct Version {
    pub version: String,
    pub revision: String,
}

#[derive(Debug)]
pub struct Pagination {
    pub page: u16,
    pub per_page: u16,
}

#[derive(Debug)]
pub struct GitLab {
    scheme: String,
    domain: String,
    port: u16,
    private_token: String,
    client: hyper::Client,
    pagination: Pagination,
}

impl GitLab {

    pub fn new(scheme: &str, domain: &str, port: u16, private_token: &str) -> GitLab {
        GitLab {
            scheme: scheme.to_string(),
            domain: domain.to_string(),
            port:   port,
            private_token: private_token.to_string(),
            client: hyper::Client::new(),
            pagination: Pagination {page: 1, per_page: 20},
        }
    }

    pub fn new_http(domain: &str, private_token: &str) -> GitLab {
        GitLab::new("http", &domain, 80, &private_token)
    }

    pub fn new_https(domain: &str, private_token: &str) -> GitLab {
        GitLab::new("https", &domain, 443, &private_token)
    }

    pub fn build_url(&self, command: &str) -> String {
        format!("{}://{}:{}/api/v{}/{}?private_token={}&page={}&per_page={}",
                                self.scheme,
                                self.domain,
                                self.port,
                                API_VERSION,
                                command,
                                self.private_token,
                                self.pagination.page,
                                self.pagination.per_page)
    }

    pub fn attempt_connection(&self) -> Result<hyper::client::Response, hyper::Error> {
        // self.get("version")
        let url = self.build_url("version");
        // Close connections after each GET.
        let res = self.client.get(&url).header(hyper::header::Connection::close()).send();

        res
    }

    pub fn set_pagination(&mut self, pagination: Pagination) {
        self.pagination = pagination;
    }

    pub fn get<T>(&self, command: &str) -> Result<T, rustc_serialize::json::DecoderError>
            where T: rustc_serialize::Decodable {

        let url = self.build_url(command);
        let mut res: hyper::client::Response =
                        self.client
                        .get(&url)
                        .header(hyper::header::Connection::close())
                        .send()
                        .unwrap();

        let mut body = String::new();
        res.read_to_string(&mut body).unwrap();

        rustc_serialize::json::decode(body.as_str())
    }

    pub fn version(&self) -> Result<Version, rustc_serialize::json::DecoderError> {
        self.get("version")
    }

    pub fn groups(&self) -> Result<groups::Groups, rustc_serialize::json::DecoderError> {
        self.get("groups")
    }

    pub fn projects(&self) {
        // let mut res: hyper::client::Response = self.get("projects").unwrap();
        let url = self.build_url("projects");
        let mut res: hyper::client::Response =
                        self.client
                        .get(&url)
                        .header(hyper::header::Connection::close())
                        .send()
                        .unwrap();
        println!("####################################################################");
        println!("res: {:?}", res);
        println!("####################################################################");
        println!("Response: {}", res.status);
        println!("####################################################################");
        println!("Headers:\n{}", res.headers);
        println!("####################################################################");

        // let fresh_request = Request::get(url);
        // let streaming_request = fresh_request.start();
        // let mut response = streaming_request.send();
        // Ok(response.read_to_string())

        // let mut body = Vec::new::<u8>();
        // body.resize(, 0);
        // let result = res.read_exact(&body);

        // println!("####################################################################");
        println!("----------------------------");
        let mut body = String::new();
        println!("----------------------------");
        res.read_to_string(&mut body).unwrap();
        // println!("####################################################################");
        // let result = res.read_to_string(&mut body);
        // println!("####################################################################");
        // println!("body:\n{}", body);

        let projects: projects::Projects = rustc_serialize::json::decode(body.as_str()).unwrap();
        println!("{}", projects.p[0].description);

    }

    // pub fn projects(&self) -> ProjectManager {
    //     ProjectManager()
    // }
}

#[cfg(test)]
mod tests {
    use std::env;
    use gitlab::GitLab;

    #[test]
    fn list_groups() {
        let token = match env::var("GITLAB_TOKEN") {
            Ok(val) => val,
            Err(_)  => panic!("Please set environment variable 'GITLAB_TOKEN'"),
        };

        let mut gl = GitLab::new_https("gitlab.com", &token);
        gl.set_pagination(Pagination{page: 1, per_page: 100});
        println!("gl: {:?}", gl);

        let groups = gl.groups().unwrap();
        println!("groups: {:?}", groups);
    }

    #[test]
    fn list_projects() {
        let token = match env::var("GITLAB_TOKEN") {
            Ok(val) => val,
            Err(_)  => panic!("Please set environment variable 'GITLAB_TOKEN'"),
        };

        let gl = GitLab::new_https("gitlab.com", &token);
        println!("gl: {:?}", gl);

        gl.projects();
        // assert_eq!(gl.attempt_connection().unwrap().status, hyper::Ok);

    }
}
<|endoftext|>


<commit_before>//! ROM (cartridge) emulation

use std::fmt::{Show, Formatter, FormatError};
use std::io::{File, Reader, IoResult};

use super::Addressable;

/// ROM image
pub struct Rom {
    /// Full cartridge data
    data: Vec<u8>,
}

impl Rom {
    /// Load the ROM from a `Reader`
    pub fn from_reader(source: &mut Reader) -> IoResult<Rom> {
        // Only single unbanked ROMs supported for now (so only banks
        // 0 and 1 are available)
        let data = try!(source.read_exact(32 * 1024));

        Ok(Rom { data: data })
    }

    /// Load the ROM from a file
    pub fn from_file(path: &Path) -> IoResult<Rom> {
        let mut file_reader = try!(File::open(path));

        Rom::from_reader(&mut file_reader)
    }

    /// Attempt to retreive the rom's name
    pub fn get_name(&self) -> Option<String> {
        let mut name = String::with_capacity(16);

        for i in range(0, 16) {
            let c = self.data[offsets::TITLE + i].to_ascii();

            // If the name is shorter than 16bytes it's padded with 0s
            if c == 0.to_ascii() {
                break;
            }

            // Only uppercase ASCII is valid
            if !c.is_uppercase() {
                return None;
            }

            // Append new character
            name.grow(1, c.to_char());
        }

        Some(name)
    }
}

impl Addressable for Rom {
    fn get_byte(&self, offset: u16) -> u8 {
        self.data[offset as uint]
    }
}

impl Show for Rom {
    fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
        try!(write!(f, "ROM title: {}", match self.get_name() {
            Some(s) => s,
            None    => "<INVALID>".to_string(),
        }));

        Ok(())
    }
}

mod offsets {
    //! Various offset values to access special memory locations within the ROM

    /// Title. Upper case ASCII 16bytes long, padded with 0s if shorter
    pub const TITLE: uint = 0x134;
}
<commit_msg>Improved ROM title parsing<commit_after>//! ROM (cartridge) emulation

use std::fmt::{Show, Formatter, FormatError};
use std::io::{File, Reader, IoResult};

use super::Addressable;

/// ROM image
pub struct Rom {
    /// Full cartridge data
    data: Vec<u8>,
}

impl Rom {
    /// Load the ROM from a `Reader`
    pub fn from_reader(source: &mut Reader) -> IoResult<Rom> {
        // Only single unbanked ROMs supported for now (so only banks
        // 0 and 1 are available)
        let data = try!(source.read_exact(32 * 1024));

        Ok(Rom { data: data })
    }

    /// Load the ROM from a file
    pub fn from_file(path: &Path) -> IoResult<Rom> {
        let mut file_reader = try!(File::open(path));

        Rom::from_reader(&mut file_reader)
    }

    /// Attempt to retreive the rom's name
    pub fn get_name(&self) -> Option<String> {
        let mut name = String::with_capacity(16);

        for i in range(0, 16) {
            let c = self.data[offsets::TITLE + i].to_ascii();

            // If the name is shorter than 16bytes it's padded with 0s
            if c == 0.to_ascii() {
                break;
            }

            // Only uppercase ASCII is valid
            if !(c.is_uppercase() || c.is_blank() || c.is_punctuation()) {
                return None;
            }

            // Append new character
            name.grow(1, c.to_char());
        }

        Some(name)
    }
}

impl Addressable for Rom {
    fn get_byte(&self, offset: u16) -> u8 {
        self.data[offset as uint]
    }
}

impl Show for Rom {
    fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
        try!(write!(f, "'{}'", match self.get_name() {
            Some(s) => s,
            None    => "<INVALID>".to_string(),
        }));

        Ok(())
    }
}

mod offsets {
    //! Various offset values to access special memory locations within the ROM

    /// Title. Upper case ASCII 16bytes long, padded with 0s if shorter
    pub const TITLE: uint = 0x134;
}
<|endoftext|>