<commit_before>#![macro_escape]
use vm::{VM, Value, Int, Float, Function, Userdata, StackFrame};
use typecheck::{TcType, Typed, FunctionType, unit_type_tc, bool_type_tc, int_type_tc, float_type_tc};
use compiler::CallGlobal;
use std::any::{Any, AnyRefExt};
use std::boxed::BoxAny;

pub trait VMType {
    fn vm_type<'a>(&self, vm: &'a VM) -> &'a TcType;
    fn make_type(&self, vm: &VM) -> TcType {
        self.vm_type(vm).clone()
    }
}
pub trait VMValue : VMType {
    fn push(self, stack: &mut StackFrame);
    fn from_value(value: Value) -> Option<Self>;
}
impl VMType for () {
    fn vm_type<'a>(&self, _: &'a VM) -> &'a TcType {
        &unit_type_tc
    }
}
impl VMValue for () {
    fn push(self, _: &mut StackFrame) {
    }
    fn from_value(_: Value) -> Option<()> {
        Some(())
    }
}

impl VMType for int {
    fn vm_type<'a>(&self, _: &'a VM) -> &'a TcType {
        &int_type_tc
    }
}
impl VMValue for int {
    fn push(self, stack: &mut StackFrame) {
        stack.push(Int(self));
    }
    fn from_value(value: Value) -> Option<int> {
        match value {
            Int(i) => Some(i),
            _ => None
        }
    }
}
impl VMType for f64 {
    fn vm_type<'a>(&self, _: &'a VM) -> &'a TcType {
        &float_type_tc
    }
}
impl VMValue for f64 {
    fn push(self, stack: &mut StackFrame) {
        stack.push(Float(self));
    }
    fn from_value(value: Value) -> Option<f64> {
        match value {
            Float(f) => Some(f),
            _ => None
        }
    }
}
impl VMType for bool {
    fn vm_type<'a>(&self, _: &'a VM) -> &'a TcType {
        &bool_type_tc
    }
}
impl VMValue for bool {
    fn push(self, stack: &mut StackFrame) {
        stack.push(Int(if self { 1 } else { 0 }));
    }
    fn from_value(value: Value) -> Option<bool> {
        match value {
            Int(1) => Some(true),
            Int(0) => Some(false),
            _ => None
        }
    }
}
impl <T: 'static + BoxAny + Clone> VMType for Box<T> {
    fn vm_type<'a>(&self, vm: &'a VM) -> &'a TcType {
        vm.get_type::<T>()
    }
}
impl <T: 'static + BoxAny + Clone> VMValue for Box<T> {
    fn push(self, stack: &mut StackFrame) {
        stack.push(Userdata(Userdata::new(self as Box<Any>)));
    }
    fn from_value(value: Value) -> Option<Box<T>> {
        match value {
            Userdata(v) => v.data.borrow().downcast_ref::<T>().map(|x| box x.clone()),
            _ => None
        }
    }
}
impl <T: 'static> VMType for *mut T {
    fn vm_type<'a>(&self, vm: &'a VM) -> &'a TcType {
        vm.get_type::<T>()
    }
}
impl <T: 'static> VMValue for *mut T {
    fn push(self, stack: &mut StackFrame) {
        stack.push(Userdata(Userdata::new(box self as Box<Any>)));
    }
    fn from_value(value: Value) -> Option<*mut T> {
        match value {
            Userdata(v) => v.data.borrow().downcast_ref::<*mut T>().map(|x| *x),
            _ => None
        }
    }
}

fn vm_type<'a, T: VMValue>(vm: &'a VM) -> &'a TcType {
    let t: T = unsafe { ::std::mem::uninitialized() };
    let typ = t.vm_type(vm);
    unsafe { ::std::mem::forget(t) }
    typ
}

fn make_type<'a, T: VMValue>(vm: &'a VM) -> TcType {
    let t: T = unsafe { ::std::mem::uninitialized() };
    let typ = t.make_type(vm);
    unsafe { ::std::mem::forget(t) }
    typ
}

trait Get<'a> {
    fn get_function(vm: &'a VM<'a>, name: &str) -> Option<Self>;
}
macro_rules! make_get(
    ($($args:ident),*) => (
impl <'a, $($args : VMValue,)* R: VMValue> Get<'a> for Callable<'a, ($($args,)*), R> {
    fn get_function(vm: &'a VM<'a>, name: &str) -> Option<Callable<'a, ($($args,)*), R>> {
        let value = match vm.get_global(name) {
            Some((function_ref, global)) => {
                match global.type_of() {
                    &FunctionType(ref args, ref return_type) => {
                        let mut arg_iter = args.iter();
                        let ok = $({
                            arg_iter.next().unwrap() == vm_type::<$args>(vm)
                            } &&)* true;
                        if arg_iter.next().is_none() && ok && **return_type == *vm_type::<R>(vm) {
                            Some(FunctionRef { value: function_ref })
                        }
                        else {
                            None
                        }
                    }
                    _ => None
                }
            }
            None => None
        };
        match value {
            Some(value) => Some(Callable { vm: vm, value: value }),
            None => None
        }
    }
}
))

make_get!()
make_get!(A)
make_get!(A, B)
make_get!(A, B, C)
make_get!(A, B, C, D)
make_get!(A, B, C, D, E)
make_get!(A, B, C, D, E, F, G)

pub struct Callable<'a, Args, R> {
    vm: &'a VM<'a>,
    value: FunctionRef<Args, R>
}
struct FunctionRef<Args, R> {
    value: uint
}

impl <Args, R> VMType for FunctionRef<Args, R> {
    fn vm_type<'a>(&self, vm: &'a VM) -> &'a TcType {
        vm.get_type::<|Args|:'static -> R>()
    }
}

impl <Args, R> VMValue for FunctionRef<Args, R> {
    fn push(self, stack: &mut StackFrame) {
        stack.push(Function(self.value));
    }
    fn from_value(value: Value) -> Option<FunctionRef<Args, R>> {
        match value {
            Function(i) => Some(FunctionRef { value: i }),//TODO not type safe
            _ => None
        }
    }
}

impl <'a, A: VMValue, R: VMValue> Callable<'a, (A,), R> {
    pub fn call(&mut self, a: A) -> R {
        let mut vec = Vec::new();
        {
            let mut stack = StackFrame::new(&mut vec, 0, [].as_mut_slice());
            self.value.push(&mut stack);
            a.push(&mut stack);
            self.vm.execute(stack, &[CallGlobal(1)]);
        }
        vec.pop().and_then(|value| VMValue::from_value(value))
            .expect("Wrong type")
    }
}
impl <'a, A: VMValue, B: VMValue, R: VMValue> Callable<'a, (A, B), R> {
    pub fn call2(&mut self, a: A, b: B) -> R {
        let mut vec = Vec::new();
        {
            let mut stack = StackFrame::new(&mut vec, 0, [].as_mut_slice());
            self.value.push(&mut stack);
            a.push(&mut stack);
            b.push(&mut stack);
            self.vm.execute(stack, &[CallGlobal(2)]);
        }
        vec.pop().and_then(|value| VMValue::from_value(value))
            .expect("Wrong type")
    }
}

pub fn get_function<'a, T: Get<'a>>(vm: &'a VM<'a>, name: &str) -> Option<T> {
    Get::get_function(vm, name)
}

trait VMFunction {
    fn unpack_and_call(mut stack: StackFrame, f: Self);
}

macro_rules! make_vm_function(
    ($($args:ident),*) => (
impl <$($args: VMValue,)* R: VMValue> VMType for fn ($($args),*) -> R {
    #[allow(non_snake_case)]
    fn vm_type<'a>(&self, vm: &'a VM) -> &'a TcType {
        vm.get_type::<fn ($($args),*) -> R>()
    }
    #[allow(non_snake_case)]
    fn make_type(&self, vm: &VM) -> TcType {
        FunctionType(vec![$(make_type::<$args>(vm)),*], box make_type::<R>(vm))
    }
}

impl <$($args : VMValue,)* R: VMValue> VMFunction for fn ($($args),*) -> R {
    #[allow(non_snake_case, unused_mut, dead_assignment, unused_variable)]
    fn unpack_and_call(mut stack: StackFrame, f: fn ($($args),*) -> R) {
        let mut i = 0u;
        $(let $args = {
            let x = VMValue::from_value(stack[i].clone()).unwrap();
            i += 1;
            x
        });*;
        let r = f($($args),*);
        r.push(&mut stack);
    }
}
    )
)
pub fn unpack_and_call<F: VMFunction>(stack: StackFrame, f: F) {
    VMFunction::unpack_and_call(stack, f)
}

make_vm_function!()
make_vm_function!(A)
make_vm_function!(A, B)
make_vm_function!(A, B, C)
make_vm_function!(A, B, C, D)
make_vm_function!(A, B, C, D, E)
make_vm_function!(A, B, C, D, E, F)
make_vm_function!(A, B, C, D, E, F, G)

#[macro_export]
macro_rules! vm_function(
    ($func: expr) => ({
        fn wrapper(_: &VM, stack: StackFrame) {
            unpack_and_call(stack, $func)
        }
        wrapper
    })
)

#[macro_export]
macro_rules! define_function(
    ($vm: expr, $name: expr, $func: expr) => ({
        let vm = $vm;
        let (args, ret) = match $func.make_type(vm) {
            FunctionType(ref args, ref return_type) => (args.clone(), (**return_type).clone()),
            _ => fail!()
        };
        vm.extern_function($name, args, ret, vm_function!($func))
    })
)

#[cfg(test)]
mod tests {
    use super::{Get, Callable, VMType, unpack_and_call};

    use typecheck::FunctionType;
    use vm::{VM, load_script, StackFrame};
    use std::io::BufReader;

    #[test]
    fn call_function() {
        let s =
r"
fn add10(x: int) -> int {
    x + 10
}
fn mul(x: float, y: float) -> float {
    x * y
}
";
        let mut vm = VM::new();
        let mut buffer = BufReader::new(s.as_bytes());
        load_script(&mut vm, &mut buffer)
            .unwrap_or_else(|err| fail!("{}", err));
        {
            let mut f: Callable<(int,), int> = Get::get_function(&vm, "add10")
                .expect("No function");
            let result = f.call(2);
            assert_eq!(result, 12);
        }
        let mut f: Callable<(f64, f64), f64> = Get::get_function(&vm, "mul")
            .expect("No function");
        let result = f.call2(4., 5.);
        assert_eq!(result, 20.);
    }
    #[test]
    fn pass_userdata() {
        let s =
r"
fn id(x: Test) -> Test {
    x
}
";
        let mut vm = VM::new();
        fn test(test: *mut Test) -> bool {
            let test = unsafe { &mut *test };
            let x = test.x == 123;
            test.x *= 2;
            x
        }
        struct Test {
            x: int
        }
        vm.register_type::<Test>("Test")
            .unwrap_or_else(|_| fail!("Could not add type"));
        define_function!(&mut vm, "test", test);
        let mut buffer = BufReader::new(s.as_bytes());
        load_script(&mut vm, &mut buffer)
            .unwrap_or_else(|err| fail!("{}", err));

        let mut test = Test { x: 123 };
        {
            let mut f: Callable<(*mut Test,), *mut Test> = Get::get_function(&vm, "id")
                .expect("No function id");
            let result = f.call(&mut test);
            assert!(result == &mut test as *mut Test);
        }
        let mut f: Callable<(*mut Test,), bool> = Get::get_function(&vm, "test")
            .expect("No function test");
        let result = f.call(&mut test);
        assert!(result);
        assert_eq!(test.x, 123 * 2);
    }
}
<commit_msg>Replaced the unsafe type retrieveal functions<commit_after>#![macro_escape]
use vm::{VM, Value, Int, Float, Function, Userdata, StackFrame};
use typecheck::{TcType, Typed, FunctionType, unit_type_tc, bool_type_tc, int_type_tc, float_type_tc};
use compiler::CallGlobal;
use std::any::{Any, AnyRefExt};
use std::boxed::BoxAny;

pub trait VMType {
    fn vm_type<'a>(_: Option<Self>, vm: &'a VM) -> &'a TcType;
    fn make_type(x: Option<Self>, vm: &VM) -> TcType {
        VMType::vm_type(x, vm).clone()
    }
}
pub trait VMValue : VMType {
    fn push(self, stack: &mut StackFrame);
    fn from_value(value: Value) -> Option<Self>;
}
impl VMType for () {
    fn vm_type<'a>(_: Option<()>, _: &'a VM) -> &'a TcType {
        &unit_type_tc
    }
}
impl VMValue for () {
    fn push(self, _: &mut StackFrame) {
    }
    fn from_value(_: Value) -> Option<()> {
        Some(())
    }
}

impl VMType for int {
    fn vm_type<'a>(_: Option<int>, _: &'a VM) -> &'a TcType {
        &int_type_tc
    }
}
impl VMValue for int {
    fn push(self, stack: &mut StackFrame) {
        stack.push(Int(self));
    }
    fn from_value(value: Value) -> Option<int> {
        match value {
            Int(i) => Some(i),
            _ => None
        }
    }
}
impl VMType for f64 {
    fn vm_type<'a>(_: Option<f64>, _: &'a VM) -> &'a TcType {
        &float_type_tc
    }
}
impl VMValue for f64 {
    fn push(self, stack: &mut StackFrame) {
        stack.push(Float(self));
    }
    fn from_value(value: Value) -> Option<f64> {
        match value {
            Float(f) => Some(f),
            _ => None
        }
    }
}
impl VMType for bool {
    fn vm_type<'a>(_: Option<bool>, _: &'a VM) -> &'a TcType {
        &bool_type_tc
    }
}
impl VMValue for bool {
    fn push(self, stack: &mut StackFrame) {
        stack.push(Int(if self { 1 } else { 0 }));
    }
    fn from_value(value: Value) -> Option<bool> {
        match value {
            Int(1) => Some(true),
            Int(0) => Some(false),
            _ => None
        }
    }
}
impl <T: 'static + BoxAny + Clone> VMType for Box<T> {
    fn vm_type<'a>(_: Option<Box<T>>, vm: &'a VM) -> &'a TcType {
        vm.get_type::<T>()
    }
}
impl <T: 'static + BoxAny + Clone> VMValue for Box<T> {
    fn push(self, stack: &mut StackFrame) {
        stack.push(Userdata(Userdata::new(self as Box<Any>)));
    }
    fn from_value(value: Value) -> Option<Box<T>> {
        match value {
            Userdata(v) => v.data.borrow().downcast_ref::<T>().map(|x| box x.clone()),
            _ => None
        }
    }
}
impl <T: 'static> VMType for *mut T {
    fn vm_type<'a>(_: Option<*mut T>, vm: &'a VM) -> &'a TcType {
        vm.get_type::<T>()
    }
}
impl <T: 'static> VMValue for *mut T {
    fn push(self, stack: &mut StackFrame) {
        stack.push(Userdata(Userdata::new(box self as Box<Any>)));
    }
    fn from_value(value: Value) -> Option<*mut T> {
        match value {
            Userdata(v) => v.data.borrow().downcast_ref::<*mut T>().map(|x| *x),
            _ => None
        }
    }
}

fn vm_type<'a, T: VMValue>(vm: &'a VM) -> &'a TcType {
    VMType::vm_type(None::<T>, vm)
}

fn make_type<'a, T: VMValue>(vm: &'a VM) -> TcType {
    VMType::make_type(None::<T>, vm)
}

trait Get<'a> {
    fn get_function(vm: &'a VM<'a>, name: &str) -> Option<Self>;
}
macro_rules! make_get(
    ($($args:ident),*) => (
impl <'a, $($args : VMValue,)* R: VMValue> Get<'a> for Callable<'a, ($($args,)*), R> {
    fn get_function(vm: &'a VM<'a>, name: &str) -> Option<Callable<'a, ($($args,)*), R>> {
        let value = match vm.get_global(name) {
            Some((function_ref, global)) => {
                match global.type_of() {
                    &FunctionType(ref args, ref return_type) => {
                        let mut arg_iter = args.iter();
                        let ok = $({
                            arg_iter.next().unwrap() == vm_type::<$args>(vm)
                            } &&)* true;
                        if arg_iter.next().is_none() && ok && **return_type == *vm_type::<R>(vm) {
                            Some(FunctionRef { value: function_ref })
                        }
                        else {
                            None
                        }
                    }
                    _ => None
                }
            }
            None => None
        };
        match value {
            Some(value) => Some(Callable { vm: vm, value: value }),
            None => None
        }
    }
}
))

make_get!()
make_get!(A)
make_get!(A, B)
make_get!(A, B, C)
make_get!(A, B, C, D)
make_get!(A, B, C, D, E)
make_get!(A, B, C, D, E, F, G)

pub struct Callable<'a, Args, R> {
    vm: &'a VM<'a>,
    value: FunctionRef<Args, R>
}
struct FunctionRef<Args, R> {
    value: uint
}

impl <Args, R> VMType for FunctionRef<Args, R> {
    fn vm_type<'a>(_: Option<FunctionRef<Args, R>>, vm: &'a VM) -> &'a TcType {
        vm.get_type::<|Args|:'static -> R>()
    }
}

impl <Args, R> VMValue for FunctionRef<Args, R> {
    fn push(self, stack: &mut StackFrame) {
        stack.push(Function(self.value));
    }
    fn from_value(value: Value) -> Option<FunctionRef<Args, R>> {
        match value {
            Function(i) => Some(FunctionRef { value: i }),//TODO not type safe
            _ => None
        }
    }
}

impl <'a, A: VMValue, R: VMValue> Callable<'a, (A,), R> {
    pub fn call(&mut self, a: A) -> R {
        let mut vec = Vec::new();
        {
            let mut stack = StackFrame::new(&mut vec, 0, [].as_mut_slice());
            self.value.push(&mut stack);
            a.push(&mut stack);
            self.vm.execute(stack, &[CallGlobal(1)]);
        }
        vec.pop().and_then(|value| VMValue::from_value(value))
            .expect("Wrong type")
    }
}
impl <'a, A: VMValue, B: VMValue, R: VMValue> Callable<'a, (A, B), R> {
    pub fn call2(&mut self, a: A, b: B) -> R {
        let mut vec = Vec::new();
        {
            let mut stack = StackFrame::new(&mut vec, 0, [].as_mut_slice());
            self.value.push(&mut stack);
            a.push(&mut stack);
            b.push(&mut stack);
            self.vm.execute(stack, &[CallGlobal(2)]);
        }
        vec.pop().and_then(|value| VMValue::from_value(value))
            .expect("Wrong type")
    }
}

pub fn get_function<'a, T: Get<'a>>(vm: &'a VM<'a>, name: &str) -> Option<T> {
    Get::get_function(vm, name)
}

trait VMFunction {
    fn unpack_and_call(mut stack: StackFrame, f: Self);
}

macro_rules! make_vm_function(
    ($($args:ident),*) => (
impl <$($args: VMValue,)* R: VMValue> VMType for fn ($($args),*) -> R {
    #[allow(non_snake_case)]
    fn vm_type<'a>(_: Option<fn ($($args),*) -> R>, vm: &'a VM) -> &'a TcType {
        vm.get_type::<fn ($($args),*) -> R>()
    }
    #[allow(non_snake_case)]
    fn make_type(_: Option<fn ($($args),*) -> R>, vm: &VM) -> TcType {
        FunctionType(vec![$(make_type::<$args>(vm)),*], box make_type::<R>(vm))
    }
}

impl <$($args : VMValue,)* R: VMValue> VMFunction for fn ($($args),*) -> R {
    #[allow(non_snake_case, unused_mut, dead_assignment, unused_variable)]
    fn unpack_and_call(mut stack: StackFrame, f: fn ($($args),*) -> R) {
        let mut i = 0u;
        $(let $args = {
            let x = VMValue::from_value(stack[i].clone()).unwrap();
            i += 1;
            x
        });*;
        let r = f($($args),*);
        r.push(&mut stack);
    }
}
    )
)
pub fn unpack_and_call<F: VMFunction>(stack: StackFrame, f: F) {
    VMFunction::unpack_and_call(stack, f)
}

make_vm_function!()
make_vm_function!(A)
make_vm_function!(A, B)
make_vm_function!(A, B, C)
make_vm_function!(A, B, C, D)
make_vm_function!(A, B, C, D, E)
make_vm_function!(A, B, C, D, E, F)
make_vm_function!(A, B, C, D, E, F, G)

#[macro_export]
macro_rules! vm_function(
    ($func: expr) => ({
        fn wrapper(_: &VM, stack: StackFrame) {
            unpack_and_call(stack, $func)
        }
        wrapper
    })
)

#[macro_export]
macro_rules! define_function(
    ($vm: expr, $name: expr, $func: expr) => ({
        let vm = $vm;
        let (args, ret) = match VMType::make_type(Some($func), vm) {
            FunctionType(ref args, ref return_type) => (args.clone(), (**return_type).clone()),
            _ => fail!()
        };
        vm.extern_function($name, args, ret, vm_function!($func))
    })
)

#[cfg(test)]
mod tests {
    use super::{Get, Callable, VMType, unpack_and_call};

    use typecheck::FunctionType;
    use vm::{VM, load_script, StackFrame};
    use std::io::BufReader;

    #[test]
    fn call_function() {
        let s =
r"
fn add10(x: int) -> int {
    x + 10
}
fn mul(x: float, y: float) -> float {
    x * y
}
";
        let mut vm = VM::new();
        let mut buffer = BufReader::new(s.as_bytes());
        load_script(&mut vm, &mut buffer)
            .unwrap_or_else(|err| fail!("{}", err));
        {
            let mut f: Callable<(int,), int> = Get::get_function(&vm, "add10")
                .expect("No function");
            let result = f.call(2);
            assert_eq!(result, 12);
        }
        let mut f: Callable<(f64, f64), f64> = Get::get_function(&vm, "mul")
            .expect("No function");
        let result = f.call2(4., 5.);
        assert_eq!(result, 20.);
    }
    #[test]
    fn pass_userdata() {
        let s =
r"
fn id(x: Test) -> Test {
    x
}
";
        let mut vm = VM::new();
        fn test(test: *mut Test) -> bool {
            let test = unsafe { &mut *test };
            let x = test.x == 123;
            test.x *= 2;
            x
        }
        struct Test {
            x: int
        }
        vm.register_type::<Test>("Test")
            .unwrap_or_else(|_| fail!("Could not add type"));
        define_function!(&mut vm, "test", test);
        let mut buffer = BufReader::new(s.as_bytes());
        load_script(&mut vm, &mut buffer)
            .unwrap_or_else(|err| fail!("{}", err));

        let mut test = Test { x: 123 };
        {
            let mut f: Callable<(*mut Test,), *mut Test> = Get::get_function(&vm, "id")
                .expect("No function id");
            let result = f.call(&mut test);
            assert!(result == &mut test as *mut Test);
        }
        let mut f: Callable<(*mut Test,), bool> = Get::get_function(&vm, "test")
            .expect("No function test");
        let result = f.call(&mut test);
        assert!(result);
        assert_eq!(test.x, 123 * 2);
    }
}
<|endoftext|>


<commit_before>use display_list::DisplayListBuilder;
use euclid::Point2D;
use ipc_channel::ipc::{self, IpcSender};
use stacking_context::StackingContext;
use std::cell::Cell;
use std::sync::mpsc::{self, Sender};
use types::{ColorF, DisplayListId, Epoch, FontKey, StackingContextId};
use types::{ImageKey, ImageFormat, NativeFontHandle, PipelineId};

#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct IdNamespace(pub u32);

#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct ResourceId(pub u32);

#[derive(Serialize, Deserialize)]
pub enum ApiMsg {
    AddRawFont(FontKey, Vec<u8>),
    AddNativeFont(FontKey, NativeFontHandle),
    AddImage(ImageKey, u32, u32, ImageFormat, Vec<u8>),
    UpdateImage(ImageKey, u32, u32, ImageFormat, Vec<u8>),
    AddDisplayList(DisplayListId, PipelineId, Epoch, DisplayListBuilder),
    AddStackingContext(StackingContextId, PipelineId, Epoch, StackingContext),
    CloneApi(IpcSender<IdNamespace>),
    SetRootStackingContext(StackingContextId, ColorF, Epoch, PipelineId),
    SetRootPipeline(PipelineId),
    Scroll(Point2D<f32>),
    TranslatePointToLayerSpace(Point2D<f32>, IpcSender<Point2D<f32>>),
}

pub struct RenderApi {
    pub tx: IpcSender<ApiMsg>,
    pub id_namespace: IdNamespace,
    pub next_id: Cell<ResourceId>,
}

impl RenderApi {
    pub fn new(api_tx: IpcSender<ApiMsg>) -> RenderApi {
        RenderApi {
            tx: api_tx,
            id_namespace: IdNamespace(0),   // special case
            next_id: Cell::new(ResourceId(0)),
        }
    }

    pub fn add_raw_font(&self, bytes: Vec<u8>) -> FontKey {
        let new_id = self.next_unique_id();
        let key = FontKey::new(new_id.0, new_id.1);
        let msg = ApiMsg::AddRawFont(key, bytes);
        self.tx.send(msg).unwrap();
        key
    }

    pub fn add_native_font(&self, native_font_handle: NativeFontHandle) -> FontKey {
        let new_id = self.next_unique_id();
        let key = FontKey::new(new_id.0, new_id.1);
        let msg = ApiMsg::AddNativeFont(key, native_font_handle);
        self.tx.send(msg).unwrap();
        key
    }

    pub fn alloc_image(&self) -> ImageKey {
        let new_id = self.next_unique_id();
        ImageKey::new(new_id.0, new_id.1)
    }

    pub fn add_image(&self,
                     width: u32,
                     height: u32,
                     format: ImageFormat,
                     bytes: Vec<u8>) -> ImageKey {
        let new_id = self.next_unique_id();
        let key = ImageKey::new(new_id.0, new_id.1);
        let msg = ApiMsg::AddImage(key, width, height, format, bytes);
        self.tx.send(msg).unwrap();
        key
    }

    // TODO: Support changing dimensions (and format) during image update?
    pub fn update_image(&self,
                        key: ImageKey,
                        width: u32,
                        height: u32,
                        format: ImageFormat,
                        bytes: Vec<u8>) {
        let msg = ApiMsg::UpdateImage(key, width, height, format, bytes);
        self.tx.send(msg).unwrap();
    }

    pub fn add_display_list(&self,
                            display_list: DisplayListBuilder,
                            stacking_context: &mut StackingContext,
                            pipeline_id: PipelineId,
                            epoch: Epoch) -> Option<DisplayListId> {
        //TODO! debug_assert!(display_list.item_count() > 0, "Avoid adding empty lists!");
        let new_id = self.next_unique_id();
        let id = DisplayListId(new_id.0, new_id.1);
        stacking_context.has_stacking_contexts = stacking_context.has_stacking_contexts ||
                                                 display_list.has_stacking_contexts;
        let msg = ApiMsg::AddDisplayList(id, pipeline_id, epoch, display_list);
        self.tx.send(msg).unwrap();
        stacking_context.display_lists.push(id);

        Some(id)
    }

    pub fn add_stacking_context(&self,
                                stacking_context: StackingContext,
                                pipeline_id: PipelineId,
                                epoch: Epoch) -> StackingContextId {
        let new_id = self.next_unique_id();
        let id = StackingContextId(new_id.0, new_id.1);
        let msg = ApiMsg::AddStackingContext(id, pipeline_id, epoch, stacking_context);
        self.tx.send(msg).unwrap();
        id
    }

    pub fn set_root_pipeline(&self, pipeline_id: PipelineId) {
        let msg = ApiMsg::SetRootPipeline(pipeline_id);
        self.tx.send(msg).unwrap();
    }

    pub fn set_root_stacking_context(&self,
                                     stacking_context_id: StackingContextId,
                                     background_color: ColorF,
                                     epoch: Epoch,
                                     pipeline_id: PipelineId) {
        let msg = ApiMsg::SetRootStackingContext(stacking_context_id,
                                                 background_color,
                                                 epoch,
                                                 pipeline_id);
        self.tx.send(msg).unwrap();
    }

    pub fn scroll(&self, delta: Point2D<f32>) {
        let msg = ApiMsg::Scroll(delta);
        self.tx.send(msg).unwrap();
    }

    pub fn translate_point_to_layer_space(&self, point: &Point2D<f32>) -> Point2D<f32> {
        let (tx, rx) = ipc::channel().unwrap();
        let msg = ApiMsg::TranslatePointToLayerSpace(*point, tx);
        self.tx.send(msg).unwrap();
        rx.recv().unwrap()
    }

    pub fn clone_api(&self) -> RenderApi {
        let (tx, rx) = ipc::channel().unwrap();
        let msg = ApiMsg::CloneApi(tx);
        self.tx.send(msg).unwrap();
        RenderApi {
            tx: self.tx.clone(),
            id_namespace: rx.recv().unwrap(),
            next_id: Cell::new(ResourceId(0)),
        }
    }

    fn next_unique_id(&self) -> (u32, u32) {
        let IdNamespace(namespace) = self.id_namespace;
        let ResourceId(id) = self.next_id.get();
        self.next_id.set(ResourceId(id + 1));
        (namespace, id)
    }
}
<commit_msg>Fix a warning<commit_after>use display_list::DisplayListBuilder;
use euclid::Point2D;
use ipc_channel::ipc::{self, IpcSender};
use stacking_context::StackingContext;
use std::cell::Cell;
use types::{ColorF, DisplayListId, Epoch, FontKey, StackingContextId};
use types::{ImageKey, ImageFormat, NativeFontHandle, PipelineId};

#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct IdNamespace(pub u32);

#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct ResourceId(pub u32);

#[derive(Serialize, Deserialize)]
pub enum ApiMsg {
    AddRawFont(FontKey, Vec<u8>),
    AddNativeFont(FontKey, NativeFontHandle),
    AddImage(ImageKey, u32, u32, ImageFormat, Vec<u8>),
    UpdateImage(ImageKey, u32, u32, ImageFormat, Vec<u8>),
    AddDisplayList(DisplayListId, PipelineId, Epoch, DisplayListBuilder),
    AddStackingContext(StackingContextId, PipelineId, Epoch, StackingContext),
    CloneApi(IpcSender<IdNamespace>),
    SetRootStackingContext(StackingContextId, ColorF, Epoch, PipelineId),
    SetRootPipeline(PipelineId),
    Scroll(Point2D<f32>),
    TranslatePointToLayerSpace(Point2D<f32>, IpcSender<Point2D<f32>>),
}

pub struct RenderApi {
    pub tx: IpcSender<ApiMsg>,
    pub id_namespace: IdNamespace,
    pub next_id: Cell<ResourceId>,
}

impl RenderApi {
    pub fn new(api_tx: IpcSender<ApiMsg>) -> RenderApi {
        RenderApi {
            tx: api_tx,
            id_namespace: IdNamespace(0),   // special case
            next_id: Cell::new(ResourceId(0)),
        }
    }

    pub fn add_raw_font(&self, bytes: Vec<u8>) -> FontKey {
        let new_id = self.next_unique_id();
        let key = FontKey::new(new_id.0, new_id.1);
        let msg = ApiMsg::AddRawFont(key, bytes);
        self.tx.send(msg).unwrap();
        key
    }

    pub fn add_native_font(&self, native_font_handle: NativeFontHandle) -> FontKey {
        let new_id = self.next_unique_id();
        let key = FontKey::new(new_id.0, new_id.1);
        let msg = ApiMsg::AddNativeFont(key, native_font_handle);
        self.tx.send(msg).unwrap();
        key
    }

    pub fn alloc_image(&self) -> ImageKey {
        let new_id = self.next_unique_id();
        ImageKey::new(new_id.0, new_id.1)
    }

    pub fn add_image(&self,
                     width: u32,
                     height: u32,
                     format: ImageFormat,
                     bytes: Vec<u8>) -> ImageKey {
        let new_id = self.next_unique_id();
        let key = ImageKey::new(new_id.0, new_id.1);
        let msg = ApiMsg::AddImage(key, width, height, format, bytes);
        self.tx.send(msg).unwrap();
        key
    }

    // TODO: Support changing dimensions (and format) during image update?
    pub fn update_image(&self,
                        key: ImageKey,
                        width: u32,
                        height: u32,
                        format: ImageFormat,
                        bytes: Vec<u8>) {
        let msg = ApiMsg::UpdateImage(key, width, height, format, bytes);
        self.tx.send(msg).unwrap();
    }

    pub fn add_display_list(&self,
                            display_list: DisplayListBuilder,
                            stacking_context: &mut StackingContext,
                            pipeline_id: PipelineId,
                            epoch: Epoch) -> Option<DisplayListId> {
        //TODO! debug_assert!(display_list.item_count() > 0, "Avoid adding empty lists!");
        let new_id = self.next_unique_id();
        let id = DisplayListId(new_id.0, new_id.1);
        stacking_context.has_stacking_contexts = stacking_context.has_stacking_contexts ||
                                                 display_list.has_stacking_contexts;
        let msg = ApiMsg::AddDisplayList(id, pipeline_id, epoch, display_list);
        self.tx.send(msg).unwrap();
        stacking_context.display_lists.push(id);

        Some(id)
    }

    pub fn add_stacking_context(&self,
                                stacking_context: StackingContext,
                                pipeline_id: PipelineId,
                                epoch: Epoch) -> StackingContextId {
        let new_id = self.next_unique_id();
        let id = StackingContextId(new_id.0, new_id.1);
        let msg = ApiMsg::AddStackingContext(id, pipeline_id, epoch, stacking_context);
        self.tx.send(msg).unwrap();
        id
    }

    pub fn set_root_pipeline(&self, pipeline_id: PipelineId) {
        let msg = ApiMsg::SetRootPipeline(pipeline_id);
        self.tx.send(msg).unwrap();
    }

    pub fn set_root_stacking_context(&self,
                                     stacking_context_id: StackingContextId,
                                     background_color: ColorF,
                                     epoch: Epoch,
                                     pipeline_id: PipelineId) {
        let msg = ApiMsg::SetRootStackingContext(stacking_context_id,
                                                 background_color,
                                                 epoch,
                                                 pipeline_id);
        self.tx.send(msg).unwrap();
    }

    pub fn scroll(&self, delta: Point2D<f32>) {
        let msg = ApiMsg::Scroll(delta);
        self.tx.send(msg).unwrap();
    }

    pub fn translate_point_to_layer_space(&self, point: &Point2D<f32>) -> Point2D<f32> {
        let (tx, rx) = ipc::channel().unwrap();
        let msg = ApiMsg::TranslatePointToLayerSpace(*point, tx);
        self.tx.send(msg).unwrap();
        rx.recv().unwrap()
    }

    pub fn clone_api(&self) -> RenderApi {
        let (tx, rx) = ipc::channel().unwrap();
        let msg = ApiMsg::CloneApi(tx);
        self.tx.send(msg).unwrap();
        RenderApi {
            tx: self.tx.clone(),
            id_namespace: rx.recv().unwrap(),
            next_id: Cell::new(ResourceId(0)),
        }
    }

    fn next_unique_id(&self) -> (u32, u32) {
        let IdNamespace(namespace) = self.id_namespace;
        let ResourceId(id) = self.next_id.get();
        self.next_id.set(ResourceId(id + 1));
        (namespace, id)
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::rc::Rc;
use token::Literal;

#[derive(Clone, Debug)]
pub enum Expr {
    Func(Function),
    Atom(Atom),
    List(List),
    Quote(Quote),
}

#[derive(Clone, Debug, PartialEq)]
pub enum Atom {
    Bool(bool),
    Int(i64),
    Flt(f64),
    Str(String),
    Symbol(Symbol),
}

#[derive(Clone, Debug)]
pub struct List(Vec<Expr>);

#[derive(Clone, Debug)]
pub struct Quote(Vec<Expr>);

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Symbol(String);

#[derive(Clone)]
pub struct Function {
    name: Option<String>,
    func: Rc<Box<Fn(&[Expr]) -> Expr>>,
}

impl Function {
    fn new<S>(name: Option<S>, func: Box<Fn(&[Expr]) -> Expr>) -> Self
        where S: Into<String>,
    {
        Function { name: name.map(Into::into), func: Rc::new(func) }
    }

    fn call<'a>(&self, args: &'a [Expr]) -> Expr {
        (self.func)(args)
    }
}

impl fmt::Debug for Function {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Some(ref name) = self.name {
            write!(f, "#[{}]", name)
        } else {
            write!(f, "#\u{03BB}")
        }
    }
}

impl From<Literal> for Atom {
    fn from(x: Literal) -> Self {
        match x {
            Literal::Bool(y) => Atom::Bool(y),
            Literal::Int(y) => Atom::Int(y),
            Literal::Flt(y) => Atom::Flt(y),
            Literal::Str(y) => Atom::Str(y),
        }
    }
}

impl From<Quote> for List {
    fn from(x: Quote) -> Self {
        List(x.0)
    }
}

impl From<List> for Quote {
    fn from(x: List) -> Self {
        Quote(x.0)
    }
}

impl From<Symbol> for Atom {
    fn from(x: Symbol) -> Self {
        Atom::Symbol(x)
    }
}

fn lift(func: Box<Fn(&[Atom]) -> Atom>) -> Box<Fn(&[Expr]) -> Expr>
{
    Box::new(move |args| Expr::Atom(
        func(args.iter()
            .map(|arg| { if let &Expr::Atom(ref atom) = arg { atom.clone() } else { panic!() } })
            .collect::<Vec<_>>()
            .as_slice())
    ))
}

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

    /*
    fn add_fn(x: &[Expr]) -> Expr {
        Expr::Atom(Atom::Int(
            x.iter().map(|x| match x {
                &Expr::Atom(Atom::Int(y)) => y,
                _ => panic!()
            }).sum()))
    }
    */
    #[test]
    fn print_debug() {
        let func = Box::new(move |atoms: &[Atom]|
            Atom::Int(atoms.iter().map(|x| if let &Atom::Int(y) = x {y} else { panic!() }).sum()));
        let add = Function::new(Some("add"), lift(func));
        add.call(vec![Expr::Atom(Atom::Int(1)), Expr::Atom(Atom::Int(2))].as_slice());
    }
}
<commit_msg>Add lambda typedef<commit_after>use std::fmt;
use std::rc::Rc;
use token::Literal;

#[derive(Clone, Debug)]
pub enum Expr {
    Func(Function),
    Atom(Atom),
    List(List),
    Quote(Quote),
}

#[derive(Clone, Debug, PartialEq)]
pub enum Atom {
    Bool(bool),
    Int(i64),
    Flt(f64),
    Str(String),
    Symbol(Symbol),
}

#[derive(Clone, Debug)]
pub struct List(Vec<Expr>);

#[derive(Clone, Debug)]
pub struct Quote(Vec<Expr>);

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Symbol(String);

#[derive(Clone)]
pub struct Function {
    name: Option<String>,
    func: Rc<Lambda>,
}

type Lambda = Box<Fn(&[Expr]) -> Expr>;

impl Function {
    fn new<S>(name: Option<S>, func: Lambda) -> Self
        where S: Into<String>,
    {
        Function { name: name.map(Into::into), func: Rc::new(func) }
    }

    fn call<'a>(&self, args: &'a [Expr]) -> Expr {
        (self.func)(args)
    }
}

impl fmt::Debug for Function {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Some(ref name) = self.name {
            write!(f, "#[{}]", name)
        } else {
            write!(f, "#\u{03BB}")
        }
    }
}

impl From<Literal> for Atom {
    fn from(x: Literal) -> Self {
        match x {
            Literal::Bool(y) => Atom::Bool(y),
            Literal::Int(y) => Atom::Int(y),
            Literal::Flt(y) => Atom::Flt(y),
            Literal::Str(y) => Atom::Str(y),
        }
    }
}

impl From<Quote> for List {
    fn from(x: Quote) -> Self {
        List(x.0)
    }
}

impl From<List> for Quote {
    fn from(x: List) -> Self {
        Quote(x.0)
    }
}

impl From<Symbol> for Atom {
    fn from(x: Symbol) -> Self {
        Atom::Symbol(x)
    }
}

fn lift(func: Box<Fn(&[Atom]) -> Atom>) -> Lambda {
    Box::new(move |args| Expr::Atom(
        func(args.iter()
            .map(|arg| { if let &Expr::Atom(ref atom) = arg { atom.clone() } else { panic!() } })
            .collect::<Vec<_>>()
            .as_slice())
    ))
}

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

    #[test]
    fn print_debug() {
        let func = Box::new(move |atoms: &[Atom]|
            Atom::Int(atoms.iter().map(|x| if let &Atom::Int(y) = x {y} else { panic!() }).sum()));
        let add = Function::new(Some("add"), lift(func));
        add.call(vec![Expr::Atom(Atom::Int(1)), Expr::Atom(Atom::Int(2))].as_slice());
    }
}
<|endoftext|>


<commit_before>//! Licensed under the Apache License, Version 2.0
//! http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
//! http://opensource.org/licenses/MIT, at your
//! option. This file may not be copied, modified, or distributed
//! except according to those terms.

use std::mem;
use std::num::Int;

/// Alternate elements from two iterators until both
/// are run out
///
/// Iterator element type is `A` if `I: Iterator<A>`
#[deriving(Clone)]
pub struct Interleave {
    a: I,
    b: J,
    flag: bool,
}

impl Interleave {
    ///
    pub fn new(a: I, b: J) -> Interleave {
        Interleave{a: a, b: b, flag: false}
    }
}

impl<A, I: Iterator, J: Iterator> Iterator for Interleave {
    #[inline]
    fn next(&mut self) -> Option {
        self.flag = !self.flag;
        if self.flag {
            match self.a.next() {
                None => self.b.next(),
                r => r,
            }
        } else {
            match self.b.next() {
                None => self.a.next(),
                r => r,
            }
        }
    }
}

/// Clonable iterator adaptor to map elementwise
/// from `Iterator<A>` to `Iterator<B>`
///
/// Created with `.fn_map(..)` on an iterator
///
/// Iterator element type is `B`
pub struct FnMap {
    map: fn(A) -> B,
    iter: I,
}

impl FnMap
{
    pub fn new(iter: I, map: fn(A) -> B) -> FnMap {
        FnMap{iter: iter, map: map}
    }
}

impl<A, B, I: Iterator> Iterator for FnMap
{
    #[inline]
    fn next(&mut self) -> Option {
        self.iter.next().map(|a| (self.map)(a))
    }

    fn size_hint(&self) -> (uint, Option<uint>) {
        self.iter.size_hint()
    }
}

impl<A, B, I: DoubleEndedIterator> DoubleEndedIterator
for FnMap
{
    #[inline]
    fn next_back(&mut self) -> Option {
        self.iter.next_back().map(|a| (self.map)(a))
    }
}

impl Clone for FnMap
{
    fn clone(&self) -> FnMap {
        FnMap::new(self.iter.clone(), self.map)
    }
}

/// An iterator adaptor that allows putting back a single
/// item to the front of the iterator.
///
/// Iterator element type is `A`
#[deriving(Clone)]
pub struct PutBack {
    top: Option,
    iter: I
}

impl PutBack {
    /// Iterator element type is `A`
    #[inline]
    pub fn new(it: I) -> PutBack {
        PutBack{top: None, iter: it}
    }

    /// Put back a single value to the front of the iterator.
    ///
    /// If a value is already in the put back slot, it is overwritten.
    #[inline]
    pub fn put_back(&mut self, x: A) {
        self.top = Some(x)
    }
}

impl<A, I: Iterator> Iterator for PutBack {
    #[inline]
    fn next(&mut self) -> Option {
        match self.top {
            None => self.iter.next(),
            ref mut some => mem::replace(some, None)
        }
    }
    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        let (lo, hi) = self.iter.size_hint();
        match self.top {
            Some(_) => (lo.saturating_add(1), hi.and_then(|x| x.checked_add(1))),
            None => (lo, hi)
        }
    }
}

/// An iterator adaptor that iterates over the cartesian product of
/// the element sets of two iterators `I` and `J`.
///
/// Iterator element type is `(A, B)` if `I: Iterator<A>` and `J: Iterator<B>`
#[deriving(Clone)]
pub struct Product {
    a: I,
    a_cur: Option,
    b: J,
    b_orig: J,
}

impl<A: Clone, B, I: Iterator, J: Clone + Iterator>
    Product
{
    /// Create a new cartesian product iterator
    ///
    /// Iterator element type is `(A, B)` if `I: Iterator<A>` and `J: Iterator<B>`
    pub fn new(i: I, j: J) -> Product
    {
        let mut i = i;
        Product{a_cur: i.next(), a: i, b: j.clone(), b_orig: j}
    }
}

impl<A: Clone, I: Iterator, B, J: Clone + Iterator>
Iterator<(A, B)> for Product
{
    fn next(&mut self) -> Option<(A, B)>
    {
        let elt_b = match self.b.next() {
            None => {
                self.b = self.b_orig.clone();
                match self.b.next() {
                    None => return None,
                    Some(x) => {
                        self.a_cur = self.a.next();
                        x
                    }
                }
            }
            Some(x) => x
        };
        match self.a_cur {
            None => None,
            Some(ref a) => {
                Some((a.clone(), elt_b))
            }
        }
    }

    fn size_hint(&self) -> (uint, Option<uint>)
    {
        let (a, ah) = self.a.size_hint();
        let (b, bh) = self.b.size_hint();
        let (bo, boh) = self.b_orig.size_hint();

        // Compute a * bo + b for both lower and upper bound
        let low = a.checked_mul(bo)
                    .and_then(|x| x.checked_add(b))
                    .unwrap_or(::std::uint::MAX);
        let high = ah.and_then(|x| boh.and_then(|y| x.checked_mul(y)))
                     .and_then(|x| bh.and_then(|y| x.checked_add(y)));
        (low, high)
    }
}

/// Remove duplicates from sections of consecutive identical elements.
/// If the iterator is sorted, all elements will be unique.
///
/// Iterator element type is `A` if `I: Iterator<A>`
#[deriving(Clone)]
pub struct Dedup {
    last: Option,
    iter: I,
}

impl Dedup
{
    /// Create a new Dedup Iterator.
    pub fn new(iter: I) -> Dedup
    {
        Dedup{last: None, iter: iter}
    }
}

impl<A: Clone + PartialEq, I: Iterator> Iterator for Dedup
{
    #[inline]
    fn next(&mut self) -> Option
    {
        let mut elt;
        loop {
            elt = self.iter.next();

            match self.last {
                None => {
                    break
                }
                Some(ref x) => match elt {
                    Some(ref y) if x == y => continue,
                    _ => break,
                }
            }
        }
        self.last = elt.clone();
        elt
    }

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>)
    {
        let (lower, upper) = self.iter.size_hint();
        if self.last.is_some() || lower == 0{
            // they might all be duplicates
            (0, upper)
        } else {
            (1, upper)
        }
    }
}

/// An advanced iterator adaptor. The closure recives a reference to the iterator
/// and may pick off as many elements as it likes, to produce the next iterator element.
///
/// Iterator element type is `B`, if the return type of `F` is `Option<B>`.
#[deriving(Clone)]
pub struct Batching {
    f: F,
    iter: I,
}

impl<F, I> Batching {
    /// Create a new Batching iterator.
    pub fn new(iter: I, f: F) -> Batching
    {
        Batching{f: f, iter: iter}
    }
}

impl Option, I: Iterator>
    Iterator for Batching
{
    #[inline]
    fn next(&mut self) -> Option
    {
        (self.f)(&mut self.iter)
    }

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>)
    {
        // No information about closue behavior
        (0, None)
    }
}
<commit_msg>Simplify Dedup<commit_after>//! Licensed under the Apache License, Version 2.0
//! http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
//! http://opensource.org/licenses/MIT, at your
//! option. This file may not be copied, modified, or distributed
//! except according to those terms.

use std::mem;
use std::num::Int;

/// Alternate elements from two iterators until both
/// are run out
///
/// Iterator element type is `A` if `I: Iterator<A>`
#[deriving(Clone)]
pub struct Interleave {
    a: I,
    b: J,
    flag: bool,
}

impl Interleave {
    ///
    pub fn new(a: I, b: J) -> Interleave {
        Interleave{a: a, b: b, flag: false}
    }
}

impl<A, I: Iterator, J: Iterator> Iterator for Interleave {
    #[inline]
    fn next(&mut self) -> Option {
        self.flag = !self.flag;
        if self.flag {
            match self.a.next() {
                None => self.b.next(),
                r => r,
            }
        } else {
            match self.b.next() {
                None => self.a.next(),
                r => r,
            }
        }
    }
}

/// Clonable iterator adaptor to map elementwise
/// from `Iterator<A>` to `Iterator<B>`
///
/// Created with `.fn_map(..)` on an iterator
///
/// Iterator element type is `B`
pub struct FnMap {
    map: fn(A) -> B,
    iter: I,
}

impl FnMap
{
    pub fn new(iter: I, map: fn(A) -> B) -> FnMap {
        FnMap{iter: iter, map: map}
    }
}

impl<A, B, I: Iterator> Iterator for FnMap
{
    #[inline]
    fn next(&mut self) -> Option {
        self.iter.next().map(|a| (self.map)(a))
    }

    fn size_hint(&self) -> (uint, Option<uint>) {
        self.iter.size_hint()
    }
}

impl<A, B, I: DoubleEndedIterator> DoubleEndedIterator
for FnMap
{
    #[inline]
    fn next_back(&mut self) -> Option {
        self.iter.next_back().map(|a| (self.map)(a))
    }
}

impl Clone for FnMap
{
    fn clone(&self) -> FnMap {
        FnMap::new(self.iter.clone(), self.map)
    }
}

/// An iterator adaptor that allows putting back a single
/// item to the front of the iterator.
///
/// Iterator element type is `A`
#[deriving(Clone)]
pub struct PutBack {
    top: Option,
    iter: I
}

impl PutBack {
    /// Iterator element type is `A`
    #[inline]
    pub fn new(it: I) -> PutBack {
        PutBack{top: None, iter: it}
    }

    /// Put back a single value to the front of the iterator.
    ///
    /// If a value is already in the put back slot, it is overwritten.
    #[inline]
    pub fn put_back(&mut self, x: A) {
        self.top = Some(x)
    }
}

impl<A, I: Iterator> Iterator for PutBack {
    #[inline]
    fn next(&mut self) -> Option {
        match self.top {
            None => self.iter.next(),
            ref mut some => mem::replace(some, None)
        }
    }
    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        let (lo, hi) = self.iter.size_hint();
        match self.top {
            Some(_) => (lo.saturating_add(1), hi.and_then(|x| x.checked_add(1))),
            None => (lo, hi)
        }
    }
}

/// An iterator adaptor that iterates over the cartesian product of
/// the element sets of two iterators `I` and `J`.
///
/// Iterator element type is `(A, B)` if `I: Iterator<A>` and `J: Iterator<B>`
#[deriving(Clone)]
pub struct Product {
    a: I,
    a_cur: Option,
    b: J,
    b_orig: J,
}

impl<A: Clone, B, I: Iterator, J: Clone + Iterator>
    Product
{
    /// Create a new cartesian product iterator
    ///
    /// Iterator element type is `(A, B)` if `I: Iterator<A>` and `J: Iterator<B>`
    pub fn new(i: I, j: J) -> Product
    {
        let mut i = i;
        Product{a_cur: i.next(), a: i, b: j.clone(), b_orig: j}
    }
}

impl<A: Clone, I: Iterator, B, J: Clone + Iterator>
Iterator<(A, B)> for Product
{
    fn next(&mut self) -> Option<(A, B)>
    {
        let elt_b = match self.b.next() {
            None => {
                self.b = self.b_orig.clone();
                match self.b.next() {
                    None => return None,
                    Some(x) => {
                        self.a_cur = self.a.next();
                        x
                    }
                }
            }
            Some(x) => x
        };
        match self.a_cur {
            None => None,
            Some(ref a) => {
                Some((a.clone(), elt_b))
            }
        }
    }

    fn size_hint(&self) -> (uint, Option<uint>)
    {
        let (a, ah) = self.a.size_hint();
        let (b, bh) = self.b.size_hint();
        let (bo, boh) = self.b_orig.size_hint();

        // Compute a * bo + b for both lower and upper bound
        let low = a.checked_mul(bo)
                    .and_then(|x| x.checked_add(b))
                    .unwrap_or(::std::uint::MAX);
        let high = ah.and_then(|x| boh.and_then(|y| x.checked_mul(y)))
                     .and_then(|x| bh.and_then(|y| x.checked_add(y)));
        (low, high)
    }
}

/// Remove duplicates from sections of consecutive identical elements.
/// If the iterator is sorted, all elements will be unique.
///
/// Iterator element type is `A` if `I: Iterator<A>`
#[deriving(Clone)]
pub struct Dedup {
    last: Option,
    iter: I,
}

impl Dedup
{
    /// Create a new Dedup Iterator.
    pub fn new(iter: I) -> Dedup
    {
        Dedup{last: None, iter: iter}
    }
}

impl<A: Clone + PartialEq, I: Iterator> Iterator for Dedup
{
    #[inline]
    fn next(&mut self) -> Option
    {
        for elt in self.iter {
            match self.last {
                Some(ref x) if x == &elt => continue,
                _ => {
                    self.last = Some(elt.clone());
                    return Some(elt)
                }
            }
        }
        None
    }

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>)
    {
        let (lower, upper) = self.iter.size_hint();
        if self.last.is_some() || lower == 0 {
            // they might all be duplicates
            (0, upper)
        } else {
            (1, upper)
        }
    }
}

/// An advanced iterator adaptor. The closure recives a reference to the iterator
/// and may pick off as many elements as it likes, to produce the next iterator element.
///
/// Iterator element type is `B`, if the return type of `F` is `Option<B>`.
#[deriving(Clone)]
pub struct Batching {
    f: F,
    iter: I,
}

impl<F, I> Batching {
    /// Create a new Batching iterator.
    pub fn new(iter: I, f: F) -> Batching
    {
        Batching{f: f, iter: iter}
    }
}

impl Option, I: Iterator>
    Iterator for Batching
{
    #[inline]
    fn next(&mut self) -> Option
    {
        (self.f)(&mut self.iter)
    }

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>)
    {
        // No information about closue behavior
        (0, None)
    }
}
<|endoftext|>


<commit_before>extern crate byteorder;
pub mod rom_loader;
pub mod memory;
pub mod cpu;

use std::env;

fn main() {
    let cpu: cpu::CpuState;
    cpu::opcode::load_from_file("resources/opcodes.csv");

    match rom_loader::load_ines("roms/nestest.nes") {
      Ok(_) => (),
      Err(err) => println!("Error: {:?}", err),
    }
}

<commit_msg>short cpu loop implemented<commit_after>extern crate byteorder;
pub mod rom_loader;
pub mod memory;
pub mod cpu;

use std::env;
use cpu::CpuState;
use memory::Memory;

fn main() {
    let rom = rom_loader::load_ines("roms/nestest.nes").unwrap();
    let mut cpu: CpuState = Default::default();
    let mem:Memory = Memory::new();
    // TODO: implement loading the rom into the correct position in memory

    // TODO: handle this properly instead of just unwrapping
    let opcode_info = cpu::opcode::load_from_file("resources/opcodes.csv").unwrap();
    let executor = cpu::CpuExecutor::new(opcode_info.0);

    for i in 0..10 {
        executor.fetch_and_decode(&cpu,&mem);
        executor.execute(&cpu,&mem);
    }
}

<|endoftext|>


<commit_before>use euclid::{rect, TypedPoint2D, TypedRect};
use num::{Float, One, Zero};
use rand::distributions::{Distribution, Standard, Uniform};
use rand::Rng;
use seeded_rng;
use std::error::Error;
use std::fmt;
use std::hash::Hash;
use std::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};

/// Clamp a value to range.
pub fn clamp<C: PartialOrd + Copy>(mn: C, mx: C, x: C) -> C {
    if x < mn {
        mn
    } else if x > mx {
        mx
    } else {
        x
    }
}

/// Deterministic noise.
///
/// Turns an input value into a noise value.
///
/// # Examples
///
/// ```
/// # extern crate rand;
/// # extern crate calx;
/// # fn main() {
/// use rand::distributions::Uniform;
/// use calx::Noise;
///
/// let depth = Uniform::new_inclusive(-1.0, 1.0);
/// let z: f32 = depth.noise(&(12, 34));
/// assert_eq!(z, -0.6524992);
/// let z: f32 = depth.noise(&(34, 12));
/// assert_eq!(z, -0.56852627);
/// # }
/// ```
pub trait Noise<T> {
    fn noise(&self, seed: &impl Hash) -> T;
}

impl<T: Distribution<U>, U> Noise<U> for T {
    fn noise(&self, seed: &impl Hash) -> U { self.sample(&mut seeded_rng(&seed)) }
}

/// A deciban unit log odds value.
///
/// Log odds correspond to the Bayesian probability for a hypothesis that
/// has decibans * 1/10 log_2(10) bits of evidence in favor of it. They're
/// a bit like rolling a d20 but better.
///
/// # Examples
///
/// ```
/// use calx::Deciban;
/// assert_eq!(0.0, Deciban::new(0.5).0);
/// assert_eq!(10, Deciban::new(0.909091).0 as i32);
///
/// assert_eq!(0.5, Deciban(0.0).to_p());
/// assert_eq!(24, (Deciban(-5.0).to_p() * 100.0) as i32);
/// ```
#[derive(Copy, Clone, PartialEq, PartialOrd, Default, Debug)]
pub struct Deciban(pub f32);

impl Deciban {
    /// Build a deciban value from a probability in [0, 1).
    pub fn new(p: f32) -> Deciban {
        debug_assert!(p >= 0.0 && p < 1.0);
        Deciban(10.0 * (p / (1.0 - p)).log(10.0))
    }

    /// Convert a deciban value to the corresponding probability in [0, 1).
    pub fn to_p(self) -> f32 { 1.0 - 1.0 / (1.0 + 10.0.powf(self.0 / 10.0)) }
}

impl Distribution<Deciban> for Standard {
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> ::Deciban {
        Deciban::new(rng.gen_range(0.0, 1.0))
    }
}

impl Add for Deciban {
    type Output = Deciban;
    fn add(self, rhs: Deciban) -> Deciban { Deciban(self.0 + rhs.0) }
}

impl AddAssign for Deciban {
    fn add_assign(&mut self, rhs: Deciban) { self.0 += rhs.0; }
}

impl Sub for Deciban {
    type Output = Deciban;
    fn sub(self, rhs: Deciban) -> Deciban { Deciban(self.0 - rhs.0) }
}

impl SubAssign for Deciban {
    fn sub_assign(&mut self, rhs: Deciban) { self.0 -= rhs.0; }
}

/// Interpolate linearly between two values.
pub fn lerp<T, U, V, W>(a: U, b: U, t: T) -> W
where
    U: Add<V, Output = W> + Sub<U, Output = V> + Copy,
    V: Mul<T, Output = V>,
{
    a + (b - a) * t
}

/// Sequence of points for linearly interpolating between them.
pub struct LerpPath<T, U> {
    points: Vec<(T, U)>,
}

impl<T, U, V, W> LerpPath<T, U>
where
    U: Add<V, Output = W> + Sub<U, Output = V> + Copy,
    V: Mul<T, Output = V>,
    T: PartialOrd + Sub<T, Output = T> + Div<T, Output = T> + Copy + Zero,
{
    pub fn new(begin: (T, U), end: (T, U)) -> LerpPath<T, U> {
        let mut result = LerpPath {
            points: vec![begin],
        };
        result.add(end);
        result
    }

    pub fn add(&mut self, point: (T, U)) {
        for i in 0..self.points.len() {
            if point.0 == self.points[i].0 {
                // Avoid zero width intervals or we'll get division by zero down the road, just
                // replace the point if the position is exactly the same.
                self.points[i] = point;
                return;
            }
            if point.0 < self.points[i].0 {
                self.points.insert(i, point);
                return;
            }
        }

        self.points.push(point);
    }

    pub fn sample(&self, t: T) -> W {
        if t < self.points[0].0 {
            return lerp(self.points[0].1, self.points[0].1, T::zero());
        }

        for i in 1..self.points.len() {
            if t < self.points[i].0 {
                let scaled = (t - self.points[i - 1].0) / (self.points[i].0 - self.points[i - 1].0);
                return lerp(self.points[i - 1].1, self.points[i].1, scaled);
            }
        }

        lerp(
            self.points[self.points.len() - 1].1,
            self.points[self.points.len() - 1].1,
            T::zero(),
        )
    }
}

/// Single-pass weighted sample for iterations.
pub trait WeightedChoice {
    type Item;

    /// Choose an item from the iteration with probability weighted by item weight.
    fn weighted_choice<R: Rng, F>(self, rng: &mut R, weight_fn: F) -> Option<Self::Item>
    where
        F: Fn(&Self::Item) -> f32;
}

impl<T, I: IntoIterator<Item = T> + Sized> WeightedChoice for I {
    type Item = T;

    fn weighted_choice<R: Rng, F>(self, rng: &mut R, weight_fn: F) -> Option<Self::Item>
    where
        F: Fn(&Self::Item) -> f32,
    {
        let dist = Uniform::new(0.0, 1.0);
        let (_, ret) = self
            .into_iter()
            .fold((0.0, None), |(weight_sum, prev_item), item| {
                let item_weight = weight_fn(&item);
                debug_assert!(item_weight >= 0.0);
                let p = item_weight / (weight_sum + item_weight);
                let next_item = if dist.sample(rng) < p {
                    Some(item)
                } else {
                    prev_item
                };
                (weight_sum + item_weight, next_item)
            });
        ret
    }
}

/// Insert a 0 bit between the low 16 bits of a number.
///
/// Useful for <https://en.wikipedia.org/wiki/Z-order_curve>
#[inline(always)]
pub fn spread_bits_by_2(mut bits: u32) -> u32 {
    // from https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/
    bits &= /* --------------- */ 0b0000_0000_0000_0000_1111_1111_1111_1111;
    bits = (bits ^ (bits << 8)) & 0b0000_0000_1111_1111_0000_0000_1111_1111;
    bits = (bits ^ (bits << 4)) & 0b0000_1111_0000_1111_0000_1111_0000_1111;
    bits = (bits ^ (bits << 2)) & 0b0011_0011_0011_0011_0011_0011_0011_0011;
    bits = (bits ^ (bits << 1)) & 0b0101_0101_0101_0101_0101_0101_0101_0101;
    bits
}

/// Remove every odd bit and compact the even bits into the lower half of the number.
///
/// Useful for <https://en.wikipedia.org/wiki/Z-order_curve>
#[inline(always)]
pub fn compact_bits_by_2(mut bits: u32) -> u32 {
    // from https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/
    bits &= /* --------------- */ 0b0101_0101_0101_0101_0101_0101_0101_0101;
    bits = (bits ^ (bits >> 1)) & 0b0011_0011_0011_0011_0011_0011_0011_0011;
    bits = (bits ^ (bits >> 2)) & 0b0000_1111_0000_1111_0000_1111_0000_1111;
    bits = (bits ^ (bits >> 4)) & 0b0000_0000_1111_1111_0000_0000_1111_1111;
    bits = (bits ^ (bits >> 8)) & 0b0000_0000_0000_0000_1111_1111_1111_1111;
    bits
}

/// Repeatedly run a random generator that may fail until it succeeds.
pub fn retry_gen<R: Rng + ?Sized, T, E>(
    n_tries: usize,
    rng: &mut R,
    gen: impl Fn(&mut R) -> Result<T, E>,
) -> Result<T, E> {
    let mut ret = gen(rng);
    for _ in 0..(n_tries - 1) {
        if ret.is_ok() {
            return ret;
        }
        ret = gen(rng);
    }

    ret
}

/// Build an axis-aligned rectangle that contains the given points.
///
/// It will add unit distance to the right and bottom edges to make sure the resulting `TypedRect`
/// will contain all the points. It would beneath
///
/// # Examples
///
/// ```
/// # extern crate euclid;
/// # extern crate calx;
/// # fn main() {
/// use euclid::point2;
///
/// let points: Vec<euclid::Point2D<i32>> = vec![point2(2, 3), point2(4, 5), point2(6, 7)];
/// let rect = calx::bounding_rect(&points);
/// assert!(rect.contains(&point2(2, 3)));
/// assert!(rect.contains(&point2(6, 7)));
/// assert!(!rect.contains(&point2(7, 7)));
/// assert!(!rect.contains(&point2(2, 2)));
/// # }
/// ```
pub fn bounding_rect<'a, I, T, U>(points: I) -> TypedRect<T, U>
where
    I: IntoIterator<Item = &'a TypedPoint2D<T, U>>,
    T: Zero + One + Add + Sub<Output = T> + Ord + Copy + 'a,
    U: 'a,
{
    let mut iter = points.into_iter();
    if let Some(first) = iter.next() {
        let (mut min_x, mut min_y) = (first.x, first.y);
        let (mut max_x, mut max_y) = (first.x, first.y);

        for p in iter {
            min_x = min_x.min(p.x);
            min_y = min_y.min(p.y);
            max_x = max_x.max(p.x);
            max_y = max_y.max(p.y);
        }

        // Make the rect contain the edge points.
        max_x = max_x + T::one();
        max_y = max_y + T::one();

        rect(min_x, min_y, max_x - min_x, max_y - min_y)
    } else {
        TypedRect::zero()
    }
}

/// Error type for when you don't care about the type and just want to use a string message.
#[derive(Debug)]
pub struct GenericError(pub String);

impl Error for GenericError {}

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

/// Construct a `GenericError`.
#[macro_export]
macro_rules! err {
    ($($arg:tt)*) => ($crate::GenericError(format!($($arg)*)));
}

/// Return a `Result<_, Box<Error>>` error with `GenericError` message.
#[macro_export]
macro_rules! die {
    ($($arg:tt)*) => (return Err(Box::new(err!($($arg)*))););
}
<commit_msg>More +?Sized to Rng params<commit_after>use euclid::{rect, TypedPoint2D, TypedRect};
use num::{Float, One, Zero};
use rand::distributions::{Distribution, Standard, Uniform};
use rand::Rng;
use seeded_rng;
use std::error::Error;
use std::fmt;
use std::hash::Hash;
use std::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};

/// Clamp a value to range.
pub fn clamp<C: PartialOrd + Copy>(mn: C, mx: C, x: C) -> C {
    if x < mn {
        mn
    } else if x > mx {
        mx
    } else {
        x
    }
}

/// Deterministic noise.
///
/// Turns an input value into a noise value.
///
/// # Examples
///
/// ```
/// # extern crate rand;
/// # extern crate calx;
/// # fn main() {
/// use rand::distributions::Uniform;
/// use calx::Noise;
///
/// let depth = Uniform::new_inclusive(-1.0, 1.0);
/// let z: f32 = depth.noise(&(12, 34));
/// assert_eq!(z, -0.6524992);
/// let z: f32 = depth.noise(&(34, 12));
/// assert_eq!(z, -0.56852627);
/// # }
/// ```
pub trait Noise<T> {
    fn noise(&self, seed: &impl Hash) -> T;
}

impl<T: Distribution<U>, U> Noise<U> for T {
    fn noise(&self, seed: &impl Hash) -> U { self.sample(&mut seeded_rng(&seed)) }
}

/// A deciban unit log odds value.
///
/// Log odds correspond to the Bayesian probability for a hypothesis that
/// has decibans * 1/10 log_2(10) bits of evidence in favor of it. They're
/// a bit like rolling a d20 but better.
///
/// # Examples
///
/// ```
/// use calx::Deciban;
/// assert_eq!(0.0, Deciban::new(0.5).0);
/// assert_eq!(10, Deciban::new(0.909091).0 as i32);
///
/// assert_eq!(0.5, Deciban(0.0).to_p());
/// assert_eq!(24, (Deciban(-5.0).to_p() * 100.0) as i32);
/// ```
#[derive(Copy, Clone, PartialEq, PartialOrd, Default, Debug)]
pub struct Deciban(pub f32);

impl Deciban {
    /// Build a deciban value from a probability in [0, 1).
    pub fn new(p: f32) -> Deciban {
        debug_assert!(p >= 0.0 && p < 1.0);
        Deciban(10.0 * (p / (1.0 - p)).log(10.0))
    }

    /// Convert a deciban value to the corresponding probability in [0, 1).
    pub fn to_p(self) -> f32 { 1.0 - 1.0 / (1.0 + 10.0.powf(self.0 / 10.0)) }
}

impl Distribution<Deciban> for Standard {
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> ::Deciban {
        Deciban::new(rng.gen_range(0.0, 1.0))
    }
}

impl Add for Deciban {
    type Output = Deciban;
    fn add(self, rhs: Deciban) -> Deciban { Deciban(self.0 + rhs.0) }
}

impl AddAssign for Deciban {
    fn add_assign(&mut self, rhs: Deciban) { self.0 += rhs.0; }
}

impl Sub for Deciban {
    type Output = Deciban;
    fn sub(self, rhs: Deciban) -> Deciban { Deciban(self.0 - rhs.0) }
}

impl SubAssign for Deciban {
    fn sub_assign(&mut self, rhs: Deciban) { self.0 -= rhs.0; }
}

/// Interpolate linearly between two values.
pub fn lerp<T, U, V, W>(a: U, b: U, t: T) -> W
where
    U: Add<V, Output = W> + Sub<U, Output = V> + Copy,
    V: Mul<T, Output = V>,
{
    a + (b - a) * t
}

/// Sequence of points for linearly interpolating between them.
pub struct LerpPath<T, U> {
    points: Vec<(T, U)>,
}

impl<T, U, V, W> LerpPath<T, U>
where
    U: Add<V, Output = W> + Sub<U, Output = V> + Copy,
    V: Mul<T, Output = V>,
    T: PartialOrd + Sub<T, Output = T> + Div<T, Output = T> + Copy + Zero,
{
    pub fn new(begin: (T, U), end: (T, U)) -> LerpPath<T, U> {
        let mut result = LerpPath {
            points: vec![begin],
        };
        result.add(end);
        result
    }

    pub fn add(&mut self, point: (T, U)) {
        for i in 0..self.points.len() {
            if point.0 == self.points[i].0 {
                // Avoid zero width intervals or we'll get division by zero down the road, just
                // replace the point if the position is exactly the same.
                self.points[i] = point;
                return;
            }
            if point.0 < self.points[i].0 {
                self.points.insert(i, point);
                return;
            }
        }

        self.points.push(point);
    }

    pub fn sample(&self, t: T) -> W {
        if t < self.points[0].0 {
            return lerp(self.points[0].1, self.points[0].1, T::zero());
        }

        for i in 1..self.points.len() {
            if t < self.points[i].0 {
                let scaled = (t - self.points[i - 1].0) / (self.points[i].0 - self.points[i - 1].0);
                return lerp(self.points[i - 1].1, self.points[i].1, scaled);
            }
        }

        lerp(
            self.points[self.points.len() - 1].1,
            self.points[self.points.len() - 1].1,
            T::zero(),
        )
    }
}

/// Single-pass weighted sample for iterations.
pub trait WeightedChoice {
    type Item;

    /// Choose an item from the iteration with probability weighted by item weight.
    fn weighted_choice<R: Rng + ?Sized, F>(self, rng: &mut R, weight_fn: F) -> Option<Self::Item>
    where
        F: Fn(&Self::Item) -> f32;
}

impl<T, I: IntoIterator<Item = T> + Sized> WeightedChoice for I {
    type Item = T;

    fn weighted_choice<R: Rng + ?Sized, F>(self, rng: &mut R, weight_fn: F) -> Option<Self::Item>
    where
        F: Fn(&Self::Item) -> f32,
    {
        let dist = Uniform::new(0.0, 1.0);
        let (_, ret) = self
            .into_iter()
            .fold((0.0, None), |(weight_sum, prev_item), item| {
                let item_weight = weight_fn(&item);
                debug_assert!(item_weight >= 0.0);
                let p = item_weight / (weight_sum + item_weight);
                let next_item = if dist.sample(rng) < p {
                    Some(item)
                } else {
                    prev_item
                };
                (weight_sum + item_weight, next_item)
            });
        ret
    }
}

/// Insert a 0 bit between the low 16 bits of a number.
///
/// Useful for <https://en.wikipedia.org/wiki/Z-order_curve>
#[inline(always)]
pub fn spread_bits_by_2(mut bits: u32) -> u32 {
    // from https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/
    bits &= /* --------------- */ 0b0000_0000_0000_0000_1111_1111_1111_1111;
    bits = (bits ^ (bits << 8)) & 0b0000_0000_1111_1111_0000_0000_1111_1111;
    bits = (bits ^ (bits << 4)) & 0b0000_1111_0000_1111_0000_1111_0000_1111;
    bits = (bits ^ (bits << 2)) & 0b0011_0011_0011_0011_0011_0011_0011_0011;
    bits = (bits ^ (bits << 1)) & 0b0101_0101_0101_0101_0101_0101_0101_0101;
    bits
}

/// Remove every odd bit and compact the even bits into the lower half of the number.
///
/// Useful for <https://en.wikipedia.org/wiki/Z-order_curve>
#[inline(always)]
pub fn compact_bits_by_2(mut bits: u32) -> u32 {
    // from https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/
    bits &= /* --------------- */ 0b0101_0101_0101_0101_0101_0101_0101_0101;
    bits = (bits ^ (bits >> 1)) & 0b0011_0011_0011_0011_0011_0011_0011_0011;
    bits = (bits ^ (bits >> 2)) & 0b0000_1111_0000_1111_0000_1111_0000_1111;
    bits = (bits ^ (bits >> 4)) & 0b0000_0000_1111_1111_0000_0000_1111_1111;
    bits = (bits ^ (bits >> 8)) & 0b0000_0000_0000_0000_1111_1111_1111_1111;
    bits
}

/// Repeatedly run a random generator that may fail until it succeeds.
pub fn retry_gen<R: Rng + ?Sized, T, E>(
    n_tries: usize,
    rng: &mut R,
    gen: impl Fn(&mut R) -> Result<T, E>,
) -> Result<T, E> {
    let mut ret = gen(rng);
    for _ in 0..(n_tries - 1) {
        if ret.is_ok() {
            return ret;
        }
        ret = gen(rng);
    }

    ret
}

/// Build an axis-aligned rectangle that contains the given points.
///
/// It will add unit distance to the right and bottom edges to make sure the resulting `TypedRect`
/// will contain all the points. It would beneath
///
/// # Examples
///
/// ```
/// # extern crate euclid;
/// # extern crate calx;
/// # fn main() {
/// use euclid::point2;
///
/// let points: Vec<euclid::Point2D<i32>> = vec![point2(2, 3), point2(4, 5), point2(6, 7)];
/// let rect = calx::bounding_rect(&points);
/// assert!(rect.contains(&point2(2, 3)));
/// assert!(rect.contains(&point2(6, 7)));
/// assert!(!rect.contains(&point2(7, 7)));
/// assert!(!rect.contains(&point2(2, 2)));
/// # }
/// ```
pub fn bounding_rect<'a, I, T, U>(points: I) -> TypedRect<T, U>
where
    I: IntoIterator<Item = &'a TypedPoint2D<T, U>>,
    T: Zero + One + Add + Sub<Output = T> + Ord + Copy + 'a,
    U: 'a,
{
    let mut iter = points.into_iter();
    if let Some(first) = iter.next() {
        let (mut min_x, mut min_y) = (first.x, first.y);
        let (mut max_x, mut max_y) = (first.x, first.y);

        for p in iter {
            min_x = min_x.min(p.x);
            min_y = min_y.min(p.y);
            max_x = max_x.max(p.x);
            max_y = max_y.max(p.y);
        }

        // Make the rect contain the edge points.
        max_x = max_x + T::one();
        max_y = max_y + T::one();

        rect(min_x, min_y, max_x - min_x, max_y - min_y)
    } else {
        TypedRect::zero()
    }
}

/// Error type for when you don't care about the type and just want to use a string message.
#[derive(Debug)]
pub struct GenericError(pub String);

impl Error for GenericError {}

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

/// Construct a `GenericError`.
#[macro_export]
macro_rules! err {
    ($($arg:tt)*) => ($crate::GenericError(format!($($arg)*)));
}

/// Return a `Result<_, Box<Error>>` error with `GenericError` message.
#[macro_export]
macro_rules! die {
    ($($arg:tt)*) => (return Err(Box::new(err!($($arg)*))););
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

// FIXME: Try the efficient algorithm (takes only O(n) time with additional O(n) space)
// https://de.wikipedia.org/wiki/Suffix-Array-Induced-Sorting
pub fn bwt<F: FnMut(u8)>(mut input: Vec<u8>, mut f: F) -> Vec<u8> {
    input.push(0);

    // get the sorted suffix array
    let mut rotations = (0..input.len()).map(|i| &input[i..]).collect::<Vec<_>>();
    rotations.sort();
    let mut rots = vec![0; input.len()];

    // BWT[i] = S[SA[i] - 1]
    for i in 0..input.len() {
        if rotations[i].len() == input.len() {
            rots[i] = 0;
        } else {
            rots[i] = input[input.len() - rotations[i].len() - 1];
        }

        f(rots[i]);     // call the function with the final value
    }

    rots
}

fn occurrence_index(map: HashMap<u8, usize>) -> HashMap<u8, usize> {
    // sort the bytes and locate the index of their first occurrences
    let mut chars = map.keys().collect::<Vec<_>>();
    chars.sort();

    let mut idx = 0;
    let mut occ_map = HashMap::new();
    for i in chars {
        occ_map.insert(*i, idx);
        idx += *map.get(i).unwrap();
    }

    occ_map
}

pub fn ibwt(input: Vec<u8>) -> Vec<u8> {
    // get the byte distribution
    let mut map = HashMap::new();
    for i in &input {
        let mut count = map.entry(*i).or_insert(0);
        *count += 1;
    }

    let mut occ_map = occurrence_index(map);

    // generate the LF vector
    let mut lf = vec![0; input.len()];
    for (i, c) in input.iter().enumerate() {
        let mut val = occ_map.get_mut(&c).unwrap();
        lf[i] = *val;
        *val += 1;
    }

    let mut idx = 0;
    // construct the sequence by traversing through the LF vector
    let mut output = vec![0; input.len()];
    for i in (0..(input.len() - 1)).rev() {
        output[i] = input[idx];
        idx = lf[idx];
    }

    output.pop();
    output
}

#[derive(Clone, Debug)]
pub struct FMIndex {
    // BW-transformed data
    data: Vec<u8>,
    // forward frequency of each character in the BWT data
    // (even the (big-ass) human genome doesn't exceed u32::MAX, so it's good for us)
    cache: Vec<u32>,
    // character frequencies
    occ_map: HashMap<u8, usize>,
    // LF-mapping for backward search
    lf_vec: Vec<u32>,
}

impl FMIndex {
    pub fn new(data: Vec<u8>) -> FMIndex {
        let mut idx = 0;
        let mut map = HashMap::new();
        let mut count = vec![0; data.len() + 1];
        let bwt_data = bwt(data, |i| {
            let mut c = map.entry(i).or_insert(0);
            *c += 1;
            count[idx] = *c as u32;
            idx += 1;
        });

        let occ_map = occurrence_index(map);
        let mut lf_occ_map = occ_map.clone();
        let mut lf_vec = vec![0; bwt_data.len()];
        for (i, c) in bwt_data.iter().enumerate() {
            let mut val = lf_occ_map.get_mut(&c).unwrap();
            lf_vec[i] = *val as u32;
            *val += 1;
        }

        FMIndex {
            data: bwt_data,
            cache: count,
            occ_map: occ_map,
            lf_vec: lf_vec,
        }
    }

    fn nearest(&self, idx: usize, ch: u8) -> usize {
        match self.occ_map.get(&ch) {
            Some(occ) => {
                occ + (0..idx).rev()
                              .find(|&i| self.data[i] == ch)
                              .map(|i| self.cache[i] as usize)
                              .unwrap_or(0)
            },
            None => 0,
        }
    }

    pub fn search(&self, query: &str) -> Option<usize> {
        let mut top = 0;
        let mut bottom = self.data.len();
        for ch in query.as_bytes().iter().rev() {
            top = self.nearest(top, *ch);
            bottom = self.nearest(bottom, *ch);
        }

        for idx in top..bottom {
            let mut i = self.nearest(idx, self.data[idx]);
            let mut pos = 1;

            // Basically, we're just doing the inverse BWT
            // FIXME: Do we have to reconstruct the entire prefix?
            while self.data[i] != 0 {
                pos += 1;
                i = self.lf_vec[i] as usize;
            }

            return Some(pos % self.data.len())      // break on first find
        }

        None
    }
}
<commit_msg>Map the LF-vector with the lengths of prefix<commit_after>use std::collections::HashMap;

// Generate the BWT of input data (calls the given function with the BWT data as it's generated)
// FIXME: Try the efficient algorithm (takes only O(n) time with additional O(n) space)
// https://de.wikipedia.org/wiki/Suffix-Array-Induced-Sorting
pub fn bwt<F: FnMut(u8)>(mut input: Vec<u8>, mut f: F) -> Vec<u8> {
    input.push(0);

    // get the sorted suffix array
    let mut rotations = (0..input.len()).map(|i| &input[i..]).collect::<Vec<_>>();
    rotations.sort();
    let mut rots = vec![0; input.len()];

    // BWT[i] = S[SA[i] - 1]
    for i in 0..input.len() {
        if rotations[i].len() == input.len() {
            rots[i] = 0;
        } else {
            rots[i] = input[input.len() - rotations[i].len() - 1];
        }

        f(rots[i]);     // call the function with the final value
    }

    rots
}

// Takes a frequency map of bytes and generates the index of first occurrence
// of each byte in their sorted form
fn occurrence_index(map: HashMap<u8, usize>) -> HashMap<u8, usize> {
    // sort the bytes and locate the index of their first occurrences
    let mut chars = map.keys().collect::<Vec<_>>();
    chars.sort();

    let mut idx = 0;
    let mut occ_map = HashMap::new();
    for i in chars {
        occ_map.insert(*i, idx);
        idx += *map.get(i).unwrap();
    }

    occ_map
}

// Invert the BWT data (generate the original data)
pub fn ibwt(input: Vec<u8>) -> Vec<u8> {
    // get the byte distribution
    let mut map = HashMap::new();
    for i in &input {
        let mut count = map.entry(*i).or_insert(0);
        *count += 1;
    }

    let mut occ_map = occurrence_index(map);

    // generate the LF vector
    let mut lf = vec![0; input.len()];
    for (i, c) in input.iter().enumerate() {
        let mut val = occ_map.get_mut(&c).unwrap();
        lf[i] = *val;
        *val += 1;
    }

    let mut idx = 0;
    // construct the sequence by traversing through the LF vector
    let mut output = vec![0; input.len()];
    for i in (0..(input.len() - 1)).rev() {
        output[i] = input[idx];
        idx = lf[idx];
    }

    output.pop();
    output
}

#[derive(Clone, Debug)]
pub struct FMIndex {
    // BW-transformed data
    data: Vec<u8>,
    // forward frequency of each character in the BWT data
    // (even the (big-ass) human genome doesn't exceed u32::MAX, so it's good for us)
    cache: Vec<u32>,
    // character frequencies
    occ_map: HashMap<u8, usize>,
    // LF-mapping for backward search (FIXME: could be seeked using a file)
    lf_vec: Vec<usize>,
}

impl FMIndex {
    pub fn new(data: Vec<u8>) -> FMIndex {
        let mut idx = 0;
        let mut map = HashMap::new();
        let mut count = vec![0; data.len() + 1];
        let mut lf_vec = vec![0; data.len() + 1];

        // generate the frequency map and forward frequency vector as we transform the data
        let bwt_data = bwt(data, |i| {
            let mut c = map.entry(i).or_insert(0);
            *c += 1;
            count[idx] = *c as u32;
            idx += 1;
        });

        let occ_map = occurrence_index(map);
        let mut lf_occ_map = occ_map.clone();
        // generate the LF vector (just like inverting the BWT)
        for (i, c) in bwt_data.iter().enumerate() {
            let mut val = lf_occ_map.get_mut(&c).unwrap();
            lf_vec[i] = *val;
            *val += 1;
        }

        let mut i = 0;
        let mut counter = bwt_data.len();
        // Only difference is that we replace the LF indices with the lengths of prefix
        // from a particular position (in other words, the number of times
        // it would take us to get to the start of string).
        while bwt_data[i] != 0 {
            let next = lf_vec[i];
            lf_vec[i] = counter;
            i = next;
            counter -= 1;
        }

        FMIndex {
            data: bwt_data,
            cache: count,
            occ_map: occ_map,
            lf_vec: lf_vec,
        }
    }

    // Get the index of the nearest occurrence of a character in the BWT data
    fn nearest(&self, idx: usize, ch: u8) -> usize {
        match self.occ_map.get(&ch) {
            Some(occ) => {
                occ + (0..idx).rev()
                              .find(|&i| self.data[i] == ch)
                              .map(|i| self.cache[i] as usize)
                              .unwrap_or(0)
            },
            None => 0,
        }
    }

    // Find the positions of occurrences of sub-string in the original data.
    pub fn search(&self, query: &str) -> Vec<usize> {
        let mut top = 0;
        let mut bottom = self.data.len();
        for ch in query.as_bytes().iter().rev() {
            top = self.nearest(top, *ch);
            bottom = self.nearest(bottom, *ch);
        }

        (top..bottom).map(|idx| {
            let i = self.nearest(idx, self.data[idx]);
            // wrap around on overflow, which usually occurs only for the
            // last index of LF vector (or the first index of original string)
            self.lf_vec[i] % (self.data.len() - 1)
        }).collect()
    }
}
<|endoftext|>