<commit_before>#![feature(globs)]

extern crate graphics;
extern crate piston;
// extern crate sdl2_game_window;
extern crate glfw_game_window;

// use sdl2_game_window::GameWindowSDL2 as Window;
use glfw_game_window::WindowGLFW;
use piston::input::keyboard;
use piston::input::{
    Keyboard,
    Mouse,
    MouseCursor,
    MouseRelative,
    MouseScroll,
    Move,
    Press,
    Release,
    Text,
};
use piston::{
    Input,
    Render,
    Update
};

pub struct App {
    capture_cursor: bool
}

impl App {
    /// Creates a new application.
    pub fn new() -> App {
        App {
            capture_cursor: false
        }
    }

    fn key_press<W: piston::Window>(
        &mut self,
        window: &mut W,
        key: keyboard::Key
    ) {
        if key == keyboard::C {
            println!("Turned capture cursor on");
            self.capture_cursor = !self.capture_cursor;

            window.capture_cursor(self.capture_cursor);
        }

        println!("Pressed keyboard key '{}'", key);
    }
}

fn main() {
    let mut window = WindowGLFW::new(
        piston::shader_version::opengl::OpenGL_3_2,
        piston::WindowSettings {
            title: "Keycode".to_string(),
            size: [300, 300],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    println!("Press C to turn capture cursor on/off");

    let mut app = App::new();
    let event_settings = piston::EventSettings {
            updates_per_second: 120,
            max_frames_per_second: 60,
        };
    for e in piston::EventIterator::new(&mut window, &event_settings) {
        match e {
            Input(Press(Keyboard(key))) =>
                app.key_press(&mut window, key),
            Input(Release(Keyboard(key))) =>
                println!("Released keyboard key '{}'", key),
            Input(Press(Mouse(button))) =>
                println!("Pressed mouse button '{}'", button),
            Input(Release(Mouse(button))) =>
                println!("Released mouse button '{}'", button),
            Input(Move(MouseCursor(x, y))) =>
                println!("Mouse moved '{} {}'", x, y),
            Input(Move(MouseScroll(dx, dy))) =>
                println!("Scrolled mouse '{}, {}'", dx, dy),
            Input(Move(MouseRelative(dx, dy))) =>
                println!("Relative mouse moved '{} {}'", dx, dy),
            Input(Text(text)) => println!("Typed '{}'", text),
            Render(_) => {},
            Update(_) => {},
        }
    }
}

<commit_msg>Handle resize event<commit_after>#![feature(globs)]

extern crate graphics;
extern crate piston;
// extern crate sdl2_game_window;
extern crate glfw_game_window;

// use sdl2_game_window::WindowSDL2;
use glfw_game_window::WindowGLFW;
use piston::input::keyboard;
use piston::input::{
    Keyboard,
    Mouse,
    MouseCursor,
    MouseRelative,
    MouseScroll,
    Move,
    Press,
    Release,
    Resize,
    Text,
};
use piston::{
    Input,
    Render,
    Update
};

pub struct App {
    capture_cursor: bool
}

impl App {
    /// Creates a new application.
    pub fn new() -> App {
        App {
            capture_cursor: false
        }
    }

    fn key_press<W: piston::Window>(
        &mut self,
        window: &mut W,
        key: keyboard::Key
    ) {
        if key == keyboard::C {
            println!("Turned capture cursor on");
            self.capture_cursor = !self.capture_cursor;

            window.capture_cursor(self.capture_cursor);
        }

        println!("Pressed keyboard key '{}'", key);
    }
}

fn main() {
    let mut window = WindowGLFW::new(
        piston::shader_version::opengl::OpenGL_3_2,
        piston::WindowSettings {
            title: "Keycode".to_string(),
            size: [300, 300],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    println!("Press C to turn capture cursor on/off");

    let mut app = App::new();
    let event_settings = piston::EventSettings {
            updates_per_second: 120,
            max_frames_per_second: 60,
        };
    for e in piston::EventIterator::new(&mut window, &event_settings) {
        match e {
            Input(Press(Keyboard(key))) =>
                app.key_press(&mut window, key),
            Input(Release(Keyboard(key))) =>
                println!("Released keyboard key '{}'", key),
            Input(Press(Mouse(button))) =>
                println!("Pressed mouse button '{}'", button),
            Input(Release(Mouse(button))) =>
                println!("Released mouse button '{}'", button),
            Input(Move(MouseCursor(x, y))) =>
                println!("Mouse moved '{} {}'", x, y),
            Input(Move(MouseScroll(dx, dy))) =>
                println!("Scrolled mouse '{}, {}'", dx, dy),
            Input(Move(MouseRelative(dx, dy))) =>
                println!("Relative mouse moved '{} {}'", dx, dy),
            Input(Text(text)) => println!("Typed '{}'", text),
            Input(Resize(w, h)) => println!("Resized '{}, {}'", w, h),
            Render(_) => {},
            Update(_) => {},
        }
    }
}

<|endoftext|>


<commit_before>#[derive(Debug)]
pub enum Error {
	IO(std::io::Error),
	Header,
	Trailer,
	Xref(XrefError),
	Offset(usize),
	Parse {offset: usize},
}

#[derive(Debug)]
pub enum XrefError {
	Parse,
	Start,
	PrevStart,
	StreamStart,
}

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

impl From<std::io::Error> for Error {
	fn from(err: std::io::Error) -> Error {
		Error::IO(err)
	}
}
<commit_msg>Add error descriptions.<commit_after>use std::fmt;

#[derive(Debug)]
pub enum Error {
	IO(std::io::Error),
	Header,
	Trailer,
	Xref(XrefError),
	Offset(usize),
	Parse {offset: usize},
}

impl fmt::Display for Error {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		match self {
			Error::IO(e) => e.fmt(f),
			Error::Header => write!(f, "Invalid file header"),
			Error::Trailer => write!(f, "Invalid file trailer"),
			Error::Xref(e) => write!(f, "Invalid cross-reference table ({})", e),
			Error::Offset(o) => write!(f, "Invalid file offset: {}", o),
			Error::Parse{offset, ..} => write!(f, "Invalid object at byte {}", offset),
		}
    }
}

impl std::error::Error for Error {}

#[derive(Debug)]
pub enum XrefError {
	Parse,
	Start,
	PrevStart,
	StreamStart,
}

impl fmt::Display for XrefError {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		match self {
			XrefError::Parse => write!(f, "could not parse xref"),
			XrefError::Start => write!(f, "invalid start value"),
			XrefError::PrevStart => write!(f, "invalid start value in Prev field"),
			XrefError::StreamStart => write!(f, "invalid stream start value"),
		}
    }
}

impl std::error::Error for XrefError {}

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

impl From<std::io::Error> for Error {
	fn from(err: std::io::Error) -> Error {
		Error::IO(err)
	}
}
<|endoftext|>


<commit_before>use std::ops::{Neg, Add, AddAssign, Sub, SubAssign, Mul, MulAssign};
use std::cmp::Ordering;
use rand::{Rand, Rng};
use serde::{Serialize, Deserialize};

// The field size.
const P: u128 = (1 << 127) - 1;

// A finite field element.
//
// It is consistent iff 0 <= self.0 <= P.
// Note that this implies that the zero element has two internal representations.
#[derive(Clone, Copy, Default, Debug)]
pub struct Fp(u128);

impl Serialize for Fp {
    #[inline]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ::serde::Serializer
    {
        use serde::ser::SerializeTuple;

        // TODO serde currently does not support u128 natively
        let (h, l) = as_limbs(u128::from(*self));
        let mut tup = serializer.serialize_tuple(2)?;
        tup.serialize_element(&h)?;
        tup.serialize_element(&l)?;
        tup.end()
    }
}

impl<'de> Deserialize<'de> for Fp {
    #[inline]
    fn deserialize<D>(deserializer: D) -> Result<Fp, D::Error>
        where D: ::serde::Deserializer<'de>
    {
        use serde::de;

        // TODO serde currently does not support u128 natively
        struct Visitor;
        impl<'de> ::serde::de::Visitor<'de> for Visitor {
            type Value = Fp;

            fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                formatter.write_str("a pair (h, l) of u64 representing an u128 x = h||l \
                                    such that 0 <= x < p where p = 2**127 - 1")
            }

            fn visit_seq<A>(self, mut a: A) -> Result<Fp, A::Error>
                where A: de::SeqAccess<'de>
            {
                let h: u64 = a.next_element()?.ok_or(de::Error::invalid_length(0, &self))?;
                let l: u64 = a.next_element()?.ok_or(de::Error::invalid_length(1, &self))?;
                let x = ((h as u128) << 64) | (l as u128);
                if x >= P {
                    let unexp_str = format!("the u128 with value {:x}", x);
                    let unexp = de::Unexpected::Other(&unexp_str);
                    return Err(de::Error::invalid_value(unexp, &self));
                }
                Ok(Fp::from_u127(x))
            }
        }

        deserializer.deserialize_tuple(2, Visitor { })
    }
}

#[inline]
fn as_limbs(x: u128) -> (u64, u64) {
    ((x >> 64) as u64, x as u64)
}

trait Reduce: Sized {
    fn reduce_once(self) -> u128;

    #[inline]
    fn reduce_once_assert(self) -> u128 {
        let red: u128 = self.reduce_once();
        debug_assert!(red <= P);
        red
    }
}

impl Reduce for u128 {
    #[inline]
    fn reduce_once(self) -> u128 {
        (self & P) + (self >> 127)
    }
}

impl Reduce for (u128, u128) {
    #[inline]
    fn reduce_once(self) -> u128 {
        let (h, l) = self;
        // shift = (h, l) >> 127
        let shift = (h << 1) | (l >> 127);
        (l & P) + shift
    }
}

impl Fp {
    #[inline]
    pub fn from_u127(x: u128) -> Self {
        // x == P is explicitly allowed.
        // This introduces a negligible bias towards the zero element
        // if x is uniformly random from {0,1}^127.
        debug_assert!(x <= P);
        Fp(x)
    }

    #[inline]
    pub fn from_u128_discard_msb(x: u128) -> Self {
        Self::from_u127(x & P)
    }

    #[inline]
    pub fn prime() -> u128 {
        P
    }
}

impl From<Fp> for u128 {
    #[inline]
    fn from(x: Fp) -> u128 {
        let red = x.0.reduce_once_assert();
        if red == P { 0 } else { red }
    }
}

impl Rand for Fp {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> Self {
        Self::from_u128_discard_msb(rng.gen::<u128>())
    }

}

impl Neg for Fp {
    type Output = Self;
    #[inline]
    fn neg(self) -> Self {
        Fp(P - self.0)
    }
}

impl Add for Fp {
    type Output = Self;
    #[inline]
    fn add(self, other: Self) -> Self {
        Fp((self.0 + other.0).reduce_once_assert())
    }
}

impl AddAssign for Fp {
    #[inline]
    fn add_assign(&mut self, other: Self) {
        *self = *self + other
    }
}

impl Sub for Fp {
    type Output = Self;
    #[inline]
    fn sub(self, other: Self) -> Self {
        self + (-other)
    }
}

impl SubAssign for Fp {
    #[inline]
    fn sub_assign(&mut self, other: Self) {
        *self = *self - other
    }
}

impl Mul for Fp {
    type Output = Self;
    #[inline]
    fn mul(self, other: Self) -> Self {
        let (sh, sl) = as_limbs(self.0);
        let (oh, ol) = as_limbs(other.0);

        // (64 bits * 63 bits) + (64 bits * 63 bits) = 128 bits
        let m: u128 = (sh as u128 * ol as u128) + (oh as u128 * sl as u128);
        let (mh, ml) = as_limbs(m);

        // (64 bits * 64 bits) + 128 bits = 129 bits
        let (rl, carry) = (sl as u128 * ol as u128).overflowing_add((ml as u128) << 64);

        // (63 bits * 63 bits) + 64 bits + 1 bit = 127 bits
        let rh: u128 = (sh as u128 * oh as u128) + (mh as u128) + (carry as u128);

        Fp((rh, rl).reduce_once().reduce_once_assert())
    }
}

impl MulAssign for Fp {
    #[inline]
    fn mul_assign(&mut self, other: Self) {
        *self = *self * other
    }
}

impl PartialEq for Fp {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        u128::from(*self) == u128::from(*other)
    }
}

impl Eq for Fp {}

impl PartialOrd for Fp {
    #[inline]
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        u128::from(*self).partial_cmp(&u128::from(*other))
    }
}

impl Ord for Fp {
    #[inline]
    fn cmp(&self, other: &Self) -> Ordering {
        self.partial_cmp(&other).unwrap()
    }
}

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

    #[test]
    fn neg() {
        assert_eq!(-Fp(0), Fp(0));
        assert_eq!(-Fp(5), Fp(P - 5));
    }

    #[test]
    fn add() {
        assert_eq!(Fp(7) + Fp(5), Fp(12));
        assert_eq!(Fp(P - 2) + Fp(5), Fp(3));
        assert_eq!(
            Fp(75661398932549814984099328258351945610) + Fp(154440289138086217180118920884960981429),
            Fp(59960504610166800432530945427428821312)
        );
    }

    #[test]
    fn sub() {
        assert_eq!(Fp(7) - Fp(5), Fp(2));
        assert_eq!(Fp(4) - Fp(8), Fp(P - 4));
    }

    #[test]
    fn mul() {
        assert_eq!(Fp(4) * Fp(3), Fp(12));
        assert_eq!(Fp(P) * Fp(291298091), Fp(0));
        assert_eq!(
            Fp(14766549069271113692204649107775507741) * Fp(153613967287097206589234951623852979690),
            Fp(113548737858505840193892055835373785352)
        );
        // Two reductions are necessary for the following example.
        assert_eq!(
            Fp(75661398932549814984099328258351945610) * Fp(154440289138086217180118920884960981429),
            Fp(109146875586984049909139102289297416971)
        );
    }

    #[test]
    fn eq() {
        assert_eq!(Fp(0), Fp(P));
        assert!(Fp(17) != Fp(4));
        assert!(Fp(0) != Fp(4));
        assert!(Fp(P) != Fp(17));
    }

    #[test]
    fn assign() {
        let mut a = Fp(17);

        a += Fp(3);
        assert_eq!(a, Fp(20));

        a -= Fp(5);
        assert_eq!(a, Fp(15));

        a *= Fp(2);
        assert_eq!(a, Fp(30));
    }
}
<commit_msg>Remove useless modular reduction<commit_after>use std::ops::{Neg, Add, AddAssign, Sub, SubAssign, Mul, MulAssign};
use std::cmp::Ordering;
use rand::{Rand, Rng};
use serde::{Serialize, Deserialize};

// The field size.
const P: u128 = (1 << 127) - 1;

// A finite field element.
//
// It is consistent iff 0 <= self.0 <= P.
// Note that this implies that the zero element has two internal representations.
#[derive(Clone, Copy, Default, Debug)]
pub struct Fp(u128);

impl Serialize for Fp {
    #[inline]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ::serde::Serializer
    {
        use serde::ser::SerializeTuple;

        // TODO serde currently does not support u128 natively
        let (h, l) = as_limbs(u128::from(*self));
        let mut tup = serializer.serialize_tuple(2)?;
        tup.serialize_element(&h)?;
        tup.serialize_element(&l)?;
        tup.end()
    }
}

impl<'de> Deserialize<'de> for Fp {
    #[inline]
    fn deserialize<D>(deserializer: D) -> Result<Fp, D::Error>
        where D: ::serde::Deserializer<'de>
    {
        use serde::de;

        // TODO serde currently does not support u128 natively
        struct Visitor;
        impl<'de> ::serde::de::Visitor<'de> for Visitor {
            type Value = Fp;

            fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                formatter.write_str("a pair (h, l) of u64 representing an u128 x = h||l \
                                    such that 0 <= x < p where p = 2**127 - 1")
            }

            fn visit_seq<A>(self, mut a: A) -> Result<Fp, A::Error>
                where A: de::SeqAccess<'de>
            {
                let h: u64 = a.next_element()?.ok_or(de::Error::invalid_length(0, &self))?;
                let l: u64 = a.next_element()?.ok_or(de::Error::invalid_length(1, &self))?;
                let x = ((h as u128) << 64) | (l as u128);
                if x >= P {
                    let unexp_str = format!("the u128 with value {:x}", x);
                    let unexp = de::Unexpected::Other(&unexp_str);
                    return Err(de::Error::invalid_value(unexp, &self));
                }
                Ok(Fp::from_u127(x))
            }
        }

        deserializer.deserialize_tuple(2, Visitor { })
    }
}

#[inline]
fn as_limbs(x: u128) -> (u64, u64) {
    ((x >> 64) as u64, x as u64)
}

trait Reduce: Sized {
    fn reduce_once(self) -> u128;

    #[inline]
    fn reduce_once_assert(self) -> u128 {
        let red: u128 = self.reduce_once();
        debug_assert!(red <= P);
        red
    }
}

impl Reduce for u128 {
    #[inline]
    fn reduce_once(self) -> u128 {
        (self & P) + (self >> 127)
    }
}

impl Reduce for (u128, u128) {
    #[inline]
    fn reduce_once(self) -> u128 {
        let (h, l) = self;
        // shift = (h, l) >> 127
        let shift = (h << 1) | (l >> 127);
        (l & P) + shift
    }
}

impl Fp {
    #[inline]
    pub fn from_u127(x: u128) -> Self {
        // x == P is explicitly allowed.
        // This introduces a negligible bias towards the zero element
        // if x is uniformly random from {0,1}^127.
        debug_assert!(x <= P);
        Fp(x)
    }

    #[inline]
    pub fn from_u128_discard_msb(x: u128) -> Self {
        Self::from_u127(x & P)
    }

    #[inline]
    pub fn prime() -> u128 {
        P
    }
}

impl From<Fp> for u128 {
    #[inline]
    fn from(x: Fp) -> u128 {
        if x.0 == P { 0 } else { x.0 }
    }
}

impl Rand for Fp {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> Self {
        Self::from_u128_discard_msb(rng.gen::<u128>())
    }

}

impl Neg for Fp {
    type Output = Self;
    #[inline]
    fn neg(self) -> Self {
        Fp(P - self.0)
    }
}

impl Add for Fp {
    type Output = Self;
    #[inline]
    fn add(self, other: Self) -> Self {
        Fp((self.0 + other.0).reduce_once_assert())
    }
}

impl AddAssign for Fp {
    #[inline]
    fn add_assign(&mut self, other: Self) {
        *self = *self + other
    }
}

impl Sub for Fp {
    type Output = Self;
    #[inline]
    fn sub(self, other: Self) -> Self {
        self + (-other)
    }
}

impl SubAssign for Fp {
    #[inline]
    fn sub_assign(&mut self, other: Self) {
        *self = *self - other
    }
}

impl Mul for Fp {
    type Output = Self;
    #[inline]
    fn mul(self, other: Self) -> Self {
        let (sh, sl) = as_limbs(self.0);
        let (oh, ol) = as_limbs(other.0);

        // (64 bits * 63 bits) + (64 bits * 63 bits) = 128 bits
        let m: u128 = (sh as u128 * ol as u128) + (oh as u128 * sl as u128);
        let (mh, ml) = as_limbs(m);

        // (64 bits * 64 bits) + 128 bits = 129 bits
        let (rl, carry) = (sl as u128 * ol as u128).overflowing_add((ml as u128) << 64);

        // (63 bits * 63 bits) + 64 bits + 1 bit = 127 bits
        let rh: u128 = (sh as u128 * oh as u128) + (mh as u128) + (carry as u128);

        Fp((rh, rl).reduce_once().reduce_once_assert())
    }
}

impl MulAssign for Fp {
    #[inline]
    fn mul_assign(&mut self, other: Self) {
        *self = *self * other
    }
}

impl PartialEq for Fp {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        u128::from(*self) == u128::from(*other)
    }
}

impl Eq for Fp {}

impl PartialOrd for Fp {
    #[inline]
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        u128::from(*self).partial_cmp(&u128::from(*other))
    }
}

impl Ord for Fp {
    #[inline]
    fn cmp(&self, other: &Self) -> Ordering {
        self.partial_cmp(&other).unwrap()
    }
}

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

    #[test]
    fn neg() {
        assert_eq!(-Fp(0), Fp(0));
        assert_eq!(-Fp(5), Fp(P - 5));
    }

    #[test]
    fn add() {
        assert_eq!(Fp(7) + Fp(5), Fp(12));
        assert_eq!(Fp(P - 2) + Fp(5), Fp(3));
        assert_eq!(
            Fp(75661398932549814984099328258351945610) + Fp(154440289138086217180118920884960981429),
            Fp(59960504610166800432530945427428821312)
        );
    }

    #[test]
    fn sub() {
        assert_eq!(Fp(7) - Fp(5), Fp(2));
        assert_eq!(Fp(4) - Fp(8), Fp(P - 4));
    }

    #[test]
    fn mul() {
        assert_eq!(Fp(4) * Fp(3), Fp(12));
        assert_eq!(Fp(P) * Fp(291298091), Fp(0));
        assert_eq!(
            Fp(14766549069271113692204649107775507741) * Fp(153613967287097206589234951623852979690),
            Fp(113548737858505840193892055835373785352)
        );
        // Two reductions are necessary for the following example.
        assert_eq!(
            Fp(75661398932549814984099328258351945610) * Fp(154440289138086217180118920884960981429),
            Fp(109146875586984049909139102289297416971)
        );
    }

    #[test]
    fn eq() {
        assert_eq!(Fp(0), Fp(P));
        assert!(Fp(17) != Fp(4));
        assert!(Fp(0) != Fp(4));
        assert!(Fp(P) != Fp(17));
    }

    #[test]
    fn assign() {
        let mut a = Fp(17);

        a += Fp(3);
        assert_eq!(a, Fp(20));

        a -= Fp(5);
        assert_eq!(a, Fp(15));

        a *= Fp(2);
        assert_eq!(a, Fp(30));
    }
}
<|endoftext|>


<commit_before>use ::{Guard, Nav};
use ::util::{ChildIndex, SiblingIndex};

use std::clone::Clone;
// use std::iter::Iterator;

/// Fixed-layout tree with good memory locality guarantees.
///
/// This tree structure does not provide methods for arbitrarily modifying its
/// topology, but it does provide good memory locality guarantees. Internally,
/// tree data is kept in a single heap-allocated region. Records of tree edges
/// are also kept in contiguous regions of memory, so tree navigation should be
/// fast.
///
/// If the tree is extended with additional children, it may reallocate its
/// entire structure.
pub struct Tree<T> {
    data: Vec<T>, offsets: Vec<usize>, children: Vec<usize>,
}

impl<T> Tree<T> {
    // pub fn new<I: Iterator<Item=(T, I)>>(data: T, children: I) -> Self {
    //     let mut tree = Tree::empty();
    //     tree.data.push(data);
    //     tree.offsets.push(offset);
    //     tree.build(0us, children);
    //     return tree;
    // }

    // fn build<I: Iterator<Item=(T, I)>>(&mut self, node: usize, children: I) {
    //     let mut i = 0us;
    //     for (child_data, child_children) in children {
    //         self.data.push(child_data);
    //         i += 1;
    //         self.children.push(node + i);
    //     }
    //     self.offsets.push(self.offsets[self.offsets.len() - 1] + i);
    // }

    pub fn empty() -> Self {
        Tree { data: vec![], offsets: vec![], children: vec![], }
    }

    // pub fn add_node<I: Iterator<Item=T>>
    //   (&mut self, parent: usize, children: &mut I) {
    //     assert![parent == self.size()];
    //     loop {
    //         let mut child_index = 0us;
    //         let mut child_count = 0us;
    //         match children.next() {
    //             None => break,
    //             Some(c) => {

    //             },
    //         }
    //     }

    // }

    pub fn size(&self) -> usize {
        self.data.len()
    }

    fn child_count(&self, index: usize) -> usize {
        match index.checked_add(1) {
            None =>
                panic!["numerical overflow in computing child count"],
            Some(x) if x > self.size() =>
                panic!["no such child {} (only {} nodes in tree)", index, self.size()],
            Some(x) if x == self.size() =>
                self.size() - self.offsets[index],
            Some(x) =>
                self.offsets[x] - self.offsets[index],
        }
    }

    fn child_of(&self, parent: usize, index: usize) -> usize {
        assert![parent < self.size()];
        match self.offsets[parent].checked_add(index) {
            Some(x) => self.children[x],
            None => panic!["numerical overflow in computing child offset"],
        }
    }
}

pub struct DataGuard<'a, T: 'a> {
    tree: &'a Tree<T>, index: usize,
}

impl<'a, T: 'a> Guard<'a, T> for DataGuard<'a, T> {
    fn super_deref<'s>(&'s self) -> &'a T {
        &self.tree.data[self.index]
    }
}

pub struct Navigator<'a, T: 'a> {
    tree: &'a Tree<T>, path: Vec<usize>,
}

impl<'a, T: 'a> Navigator<'a, T> {
    fn index(&self) -> usize {
        self.path[self.path.len() - 1]
    }
}

impl<'a, T: 'a> Clone for Navigator<'a, T> {
    fn clone(&self) -> Self {
        Navigator { tree: self.tree, path: self.path.clone(), }
    }
}

impl<'a, T: 'a> Nav<'a> for Navigator<'a, T> {
    type Data = T;
    type DataGuard = DataGuard<'a, T>;

    fn seek_sibling(&mut self, offset: isize) {
        let new_index =
            if self.path.len() < 1 {
                SiblingIndex::Root
            } else {
                let parent = self.path[self.path.len() - 1];
                SiblingIndex::compute(self.tree.child_count(parent),
                                      parent,
                                      offset)
            }.unwrap();
        let offset_index = match self.path.pop() {
            Some(parent) =>
                self.tree.child_of(parent, new_index),
            None =>
                panic!["tree corruption"],
        };
        self.path.push(offset_index);
    }

    fn seek_child(&mut self, index: usize) {
        let new_index =
            ChildIndex::compute(self.child_count(), index).unwrap();
        let offset = self.tree.offsets[self.index()];
        let child = self.tree.children[offset + new_index];
        self.path.push(child);
    }

    fn child_count(&self) -> usize {
        self.tree.child_count(self.index())
    }

    fn at_root(&self) -> bool {
        self.path.len() == 1
    }

    fn to_parent(&mut self) {
        assert![self.path.len() <= 1, "Already at root"];
        self.path.pop();
    }

    fn to_root(&mut self) {
        self.path.clear();
        self.path.push(0);
    }

    fn data(&self) -> DataGuard<'a, T> {
        DataGuard { tree: self.tree, index: self.index(), }
    }
}
<commit_msg>Traversal-based builder for fixed trees.<commit_after>use ::{Guard, Nav};
use ::traversal::Queue;
use ::util::{ChildIndex, SiblingIndex};

use std::clone::Clone;
use std::iter::Iterator;

/// Fixed-layout tree with good memory locality guarantees.
///
/// This tree structure does not provide methods for arbitrarily modifying its
/// topology, but it does provide good memory locality guarantees. Internally,
/// tree data is kept in a single heap-allocated region. Records of tree edges
/// are also kept in contiguous regions of memory, so tree navigation should be
/// fast.
///
/// If the tree is extended with additional children, it may reallocate its
/// entire structure.
pub struct Tree<T> {
    data: Vec<T>, offsets: Vec<usize>, children: Vec<usize>,
}

impl<T> Tree<T> {
    /// Constructs a tree based on the ordering imposed by a traversal.
    ///
    /// In the resulting tree, nodes will be laid out in memory in the same
    /// order in which they are visited by the traversal imposed by `queue`.
    pub fn from_traversal<Q, I>(mut queue: Q, data: T, children: I) -> Self
        where Q: Queue<(usize, usize, T, I)>, I: Iterator<Item=(T, I)> {
            let mut tree = Tree { data: Vec::new(), offsets: Vec::new(), children: Vec::new(), };
            tree.data.push(data);
            tree.offsets.push(0);
            {
                let mut child_index = 0usize;
                for (data, children) in children {
                    queue.unshift((0, child_index, data, children));
                    child_index += 1;
                    tree.children.push(0);
                }
            }
            loop {
                match queue.shift() {
                    None => return tree,
                    Some((parent_index, index, data, children)) => {
                        tree.data.push(data);
                        tree.offsets.push(tree.children.len());
                        tree.children[tree.offsets[parent_index] + index] = index;
                        let mut child_index = 0usize;
                        for (data, children) in children {
                            queue.unshift((index, child_index, data, children));
                            child_index += 1;
                            tree.children.push(0);
                        }
                    }
                }
            }
        }

    /// Constructs a new tree with no children and the given data.
    pub fn leaf(data: T) -> Self {
        Tree { data: vec![data], offsets: vec![0], children: Vec::new(), }
    }

    pub fn size(&self) -> usize {
        self.data.len()
    }

    fn child_count(&self, index: usize) -> usize {
        match index.checked_add(1) {
            None =>
                panic!["numerical overflow in computing child count"],
            Some(x) if x > self.size() =>
                panic!["no such child {} (only {} nodes in tree)", index, self.size()],
            Some(x) if x == self.size() =>
                self.size() - self.offsets[index],
            Some(x) =>
                self.offsets[x] - self.offsets[index],
        }
    }

    fn child_of(&self, parent: usize, index: usize) -> usize {
        assert![parent < self.size()];
        match self.offsets[parent].checked_add(index) {
            Some(x) => self.children[x],
            None => panic!["numerical overflow in computing child offset"],
        }
    }
}

pub struct DataGuard<'a, T: 'a> {
    tree: &'a Tree<T>, index: usize,
}

impl<'a, T: 'a> Guard<'a, T> for DataGuard<'a, T> {
    fn super_deref<'s>(&'s self) -> &'a T {
        &self.tree.data[self.index]
    }
}

pub struct Navigator<'a, T: 'a> {
    tree: &'a Tree<T>, path: Vec<usize>,
}

impl<'a, T: 'a> Navigator<'a, T> {
    fn index(&self) -> usize {
        self.path[self.path.len() - 1]
    }
}

impl<'a, T: 'a> Clone for Navigator<'a, T> {
    fn clone(&self) -> Self {
        Navigator { tree: self.tree, path: self.path.clone(), }
    }
}

impl<'a, T: 'a> Nav<'a> for Navigator<'a, T> {
    type Data = T;
    type DataGuard = DataGuard<'a, T>;

    fn seek_sibling(&mut self, offset: isize) {
        let new_index =
            if self.path.len() < 1 {
                SiblingIndex::Root
            } else {
                let parent = self.path[self.path.len() - 1];
                SiblingIndex::compute(self.tree.child_count(parent),
                                      parent,
                                      offset)
            }.unwrap();
        let offset_index = match self.path.pop() {
            Some(parent) =>
                self.tree.child_of(parent, new_index),
            None =>
                panic!["tree corruption"],
        };
        self.path.push(offset_index);
    }

    fn seek_child(&mut self, index: usize) {
        let new_index =
            ChildIndex::compute(self.child_count(), index).unwrap();
        let offset = self.tree.offsets[self.index()];
        let child = self.tree.children[offset + new_index];
        self.path.push(child);
    }

    fn child_count(&self) -> usize {
        self.tree.child_count(self.index())
    }

    fn at_root(&self) -> bool {
        self.path.len() == 1
    }

    fn to_parent(&mut self) {
        assert![self.path.len() <= 1, "Already at root"];
        self.path.pop();
    }

    fn to_root(&mut self) {
        self.path.clear();
        self.path.push(0);
    }

    fn data(&self) -> DataGuard<'a, T> {
        DataGuard { tree: self.tree, index: self.index(), }
    }
}
<|endoftext|>


<commit_before>//! Glyph caching

extern crate freetype as ft;

use std::path::Path;
use std::collections::hash_map::{ HashMap, Entry };
use graphics::character::{ CharacterCache, Character };
use graphics::types::FontSize;
use self::ft::render_mode::RenderMode;
use { gfx, Texture };

/// An enum to represent various possible run-time errors that may occur.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Error {
    /// An error happened when creating a gfx texture.
    Texture(gfx::tex::TextureError),
    /// An error happened with the FreeType library.
    Freetype(ft::error::Error)
}

impl From<gfx::tex::TextureError> for Error {
    fn from(tex_err: gfx::tex::TextureError) -> Self {
        Error::Texture(tex_err)
    }
}

impl From<ft::error::Error> for Error {
    fn from(ft_err: ft::error::Error) -> Self {
        Error::Freetype(ft_err)
    }
}

/// A struct used for caching rendered font.
pub struct GlyphCache<'a, R> where R: gfx::Resources {
    /// The font face.
    pub face: ft::Face<'a>,
    empty_texture: Texture<R>,
    need_update: bool,
    data: HashMap<(FontSize, char), Character<Texture<R>>>
}

impl<'a, R> GlyphCache<'a, R> where R: gfx::Resources {
     /// Constructor for a GlyphCache.
    pub fn new<F>(font: &Path, factory: &mut F) -> Result<Self, Error>
        where F: gfx::Factory<R>
    {
        let freetype = try!(ft::Library::init());
        let face = try!(freetype.new_face(font, 0));
        Ok(GlyphCache {
            face: face,
            empty_texture: try!(Texture::empty(factory)),
            need_update: false,
            data: HashMap::new()
        })
    }

    /// Generate all pending characters.
    pub fn update<F>(&mut self, factory: &mut F) where F: gfx::Factory<R> {
        if self.need_update {
            let ref empty_texture = self.empty_texture;
            for (&(size, ch), value) in self.data.iter_mut().filter(
                |&(_, &mut Character { ref texture, .. })| texture == empty_texture
            ) {
                self.face.set_pixel_sizes(0, size).unwrap();
                self.face.load_char(ch as usize, ft::face::DEFAULT).unwrap();
                let glyph = self.face.glyph().get_glyph().unwrap();
                let bitmap_glyph = glyph.to_bitmap(RenderMode::Normal, None).unwrap();
                let glyph_size = glyph.advance();
                value.offset = [
                    bitmap_glyph.left() as f64,
                    bitmap_glyph.top() as f64
                ];
                value.size = [
                    (glyph_size.x >> 16) as f64,
                    (glyph_size.y >> 16) as f64
                ];
                if ch != ' ' {
                    let bitmap = bitmap_glyph.bitmap();
                    value.texture = Texture::from_memory_alpha(
                        factory,
                        bitmap.buffer(),
                        bitmap.width() as u32,
                        bitmap.rows() as u32
                    );
                }
            }
            self.need_update = false;
        }
    }
}

impl<'a, R> CharacterCache for GlyphCache<'a, R> where R: gfx::Resources {
    type Texture = Texture<R>;

    fn character(&mut self, size: FontSize, ch: char) -> &Character<Self::Texture> {
        match self.data.entry((size, ch)) {
            //returning `into_mut()' to get reference with 'a lifetime
            Entry::Occupied(v) => v.into_mut(),
            Entry::Vacant(v) => {
                if !self.need_update {
                    self.need_update = true;
                }
                v.insert(Character {
                    offset: [0.0; 2],
                    size: [0.0; 2],
                    texture: self.empty_texture.clone()
                })
            }
        }
    }
}
<commit_msg>glyph: remove unnecessary lifetime parameter from GlyphCache.<commit_after>//! Glyph caching

extern crate freetype as ft;

use std::path::Path;
use std::collections::hash_map::{ HashMap, Entry };
use graphics::character::{ CharacterCache, Character };
use graphics::types::FontSize;
use self::ft::render_mode::RenderMode;
use { gfx, Texture };

/// An enum to represent various possible run-time errors that may occur.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Error {
    /// An error happened when creating a gfx texture.
    Texture(gfx::tex::TextureError),
    /// An error happened with the FreeType library.
    Freetype(ft::error::Error)
}

impl From<gfx::tex::TextureError> for Error {
    fn from(tex_err: gfx::tex::TextureError) -> Self {
        Error::Texture(tex_err)
    }
}

impl From<ft::error::Error> for Error {
    fn from(ft_err: ft::error::Error) -> Self {
        Error::Freetype(ft_err)
    }
}

/// A struct used for caching rendered font.
pub struct GlyphCache<R> where R: gfx::Resources {
    /// The font face.
    pub face: ft::Face<'static>,
    empty_texture: Texture<R>,
    need_update: bool,
    data: HashMap<(FontSize, char), Character<Texture<R>>>
}

impl<R> GlyphCache<R> where R: gfx::Resources {
     /// Constructor for a GlyphCache.
    pub fn new<F>(font: &Path, factory: &mut F) -> Result<Self, Error>
        where F: gfx::Factory<R>
    {
        let freetype = try!(ft::Library::init());
        let face = try!(freetype.new_face(font, 0));
        Ok(GlyphCache {
            face: face,
            empty_texture: try!(Texture::empty(factory)),
            need_update: false,
            data: HashMap::new()
        })
    }

    /// Generate all pending characters.
    pub fn update<F>(&mut self, factory: &mut F) where F: gfx::Factory<R> {
        if self.need_update {
            let ref empty_texture = self.empty_texture;
            for (&(size, ch), value) in self.data.iter_mut().filter(
                |&(_, &mut Character { ref texture, .. })| texture == empty_texture
            ) {
                self.face.set_pixel_sizes(0, size).unwrap();
                self.face.load_char(ch as usize, ft::face::DEFAULT).unwrap();
                let glyph = self.face.glyph().get_glyph().unwrap();
                let bitmap_glyph = glyph.to_bitmap(RenderMode::Normal, None).unwrap();
                let glyph_size = glyph.advance();
                value.offset = [
                    bitmap_glyph.left() as f64,
                    bitmap_glyph.top() as f64
                ];
                value.size = [
                    (glyph_size.x >> 16) as f64,
                    (glyph_size.y >> 16) as f64
                ];
                if ch != ' ' {
                    let bitmap = bitmap_glyph.bitmap();
                    value.texture = Texture::from_memory_alpha(
                        factory,
                        bitmap.buffer(),
                        bitmap.width() as u32,
                        bitmap.rows() as u32
                    );
                }
            }
            self.need_update = false;
        }
    }
}

impl<R> CharacterCache for GlyphCache<R> where R: gfx::Resources {
    type Texture = Texture<R>;

    fn character(&mut self, size: FontSize, ch: char) -> &Character<Self::Texture> {
        match self.data.entry((size, ch)) {
            //returning `into_mut()' to get reference with 'a lifetime
            Entry::Occupied(v) => v.into_mut(),
            Entry::Vacant(v) => {
                if !self.need_update {
                    self.need_update = true;
                }
                v.insert(Character {
                    offset: [0.0; 2],
                    size: [0.0; 2],
                    texture: self.empty_texture.clone()
                })
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) Facebook, Inc. and its affiliates
// SPDX-License-Identifier: MIT OR Apache-2.0
#![cfg(feature = "runtime-testing")]

use serde_generate::{
    cpp, test_utils,
    test_utils::{Choice, Runtime, Test},
    CodeGeneratorConfig,
};
use std::fs::File;
use std::io::Write;
use std::process::Command;
use tempfile::tempdir;

#[test]
fn test_cpp_lcs_runtime_on_simple_date() {
    test_cpp_runtime_on_simple_date(Runtime::Lcs);
}

#[test]
fn test_cpp_bincode_runtime_on_simple_date() {
    test_cpp_runtime_on_simple_date(Runtime::Bincode);
}

fn test_cpp_runtime_on_simple_date(runtime: Runtime) {
    let registry = test_utils::get_simple_registry().unwrap();
    let dir = tempdir().unwrap();
    let header_path = dir.path().join("test.hpp");
    let mut header = File::create(&header_path).unwrap();

    let config =
        CodeGeneratorConfig::new("testing".to_string()).with_encodings(vec![runtime.into()]);
    let generator = cpp::CodeGenerator::new(&config);
    generator.output(&mut header, &registry).unwrap();

    let reference = runtime.serialize(&Test {
        a: vec![4, 6],
        b: (-3, 5),
        c: Choice::C { x: 7 },
    });

    let source_path = dir.path().join("test.cpp");
    let mut source = File::create(&source_path).unwrap();
    writeln!(
        source,
        r#"
#include <cassert>
#include "test.hpp"

using namespace testing;

int main() {{
    std::vector<uint8_t> input = {{{0}}};
    auto test = Test::{1}Deserialize(input);

    auto a = std::vector<uint32_t> {{4, 6}};
    auto b = std::tuple<int64_t, uint64_t> {{-3, 5}};
    auto c = Choice {{ Choice::C {{ 7 }} }};
    auto test2 = Test {{a, b, c}};

    assert(test == test2);

    auto output = test2.{1}Serialize();

    assert(input == output);

    input.push_back(1);
    try {{
        Test::{1}Deserialize(input);
    }} catch (...) {{
        return 0;
    }}
    return 1;
}}
"#,
        reference
            .iter()
            .map(|x| format!("0x{:02x}", x))
            .collect::<Vec<_>>()
            .join(", "),
        runtime.name(),
    )
    .unwrap();

    let status = Command::new("clang++")
        .arg("--std=c++17")
        .arg("-o")
        .arg(dir.path().join("test"))
        .arg("-I")
        .arg("runtime/cpp")
        .arg(source_path)
        .status()
        .unwrap();
    assert!(status.success());

    let status = Command::new(dir.path().join("test")).status().unwrap();
    assert!(status.success());
}

#[test]
fn test_cpp_lcs_runtime_on_supported_types() {
    test_cpp_runtime_on_supported_types(Runtime::Lcs);
}

#[test]
fn test_cpp_bincode_runtime_on_supported_types() {
    test_cpp_runtime_on_supported_types(Runtime::Bincode);
}

fn test_cpp_runtime_on_supported_types(runtime: Runtime) {
    let registry = test_utils::get_registry().unwrap();
    let dir = tempdir().unwrap();
    let header_path = dir.path().join("test.hpp");
    let mut header = File::create(&header_path).unwrap();

    let config =
        CodeGeneratorConfig::new("testing".to_string()).with_encodings(vec![runtime.into()]);
    let generator = cpp::CodeGenerator::new(&config);
    generator.output(&mut header, &registry).unwrap();

    let values = test_utils::get_sample_values(runtime.has_canonical_maps());
    let encodings = values
        .iter()
        .map(|v| {
            let bytes = runtime.serialize(&v);
            format!(
                "std::vector<uint8_t>{{{}}}",
                bytes
                    .iter()
                    .map(|x| format!("0x{:02x}", x))
                    .collect::<Vec<_>>()
                    .join(", ")
            )
        })
        .collect::<Vec<_>>()
        .join(", ");

    let source_path = dir.path().join("test.cpp");
    let mut source = File::create(&source_path).unwrap();
    writeln!(
        source,
        r#"
#include <iostream>
#include <cassert>
#include "test.hpp"

using namespace testing;

int main() {{
    try {{
        std::vector<std::vector<uint8_t>> inputs = {{{0}}};

        for (auto input: inputs) {{
            auto test = SerdeData::{1}Deserialize(input);
            auto output = test.{1}Serialize();
            assert(input == output);

            // Test simple mutations of the input.
            for (int i = 0; i < input.size(); i++) {{
                auto input2 = input;
                input2[i] ^= 0x80;
                try {{
                    auto test2 = SerdeData::{1}Deserialize(input2);
                    assert(!(test2 == test));
                }} catch (serde::deserialization_error e) {{
                    // All good
                }} catch (std::bad_alloc const &e) {{
                    // All good
                }} catch (std::length_error const &e) {{
                    // All good
                }}
            }}
        }}
        return 0;
    }} catch (char const* e) {{
        std::cout << "Error: " << e << '\n';
        return -1;
    }}
}}
"#,
        encodings,
        runtime.name(),
    )
    .unwrap();

    let status = Command::new("clang++")
        .arg("--std=c++17")
        .arg("-g")
        .arg("-o")
        .arg(dir.path().join("test"))
        .arg("-I")
        .arg("runtime/cpp")
        .arg(source_path)
        .status()
        .unwrap();
    assert!(status.success());

    // Use `.status()` instead of `.output()` to debug error outputs.
    let output = Command::new(dir.path().join("test")).output().unwrap();
    assert!(output.status.success());
}
<commit_msg>[serde generate] C++ nits<commit_after>// Copyright (c) Facebook, Inc. and its affiliates
// SPDX-License-Identifier: MIT OR Apache-2.0
#![cfg(feature = "runtime-testing")]

use serde_generate::{
    cpp, test_utils,
    test_utils::{Choice, Runtime, Test},
    CodeGeneratorConfig,
};
use std::fs::File;
use std::io::Write;
use std::process::Command;
use tempfile::tempdir;

#[test]
fn test_cpp_lcs_runtime_on_simple_date() {
    test_cpp_runtime_on_simple_date(Runtime::Lcs);
}

#[test]
fn test_cpp_bincode_runtime_on_simple_date() {
    test_cpp_runtime_on_simple_date(Runtime::Bincode);
}

fn test_cpp_runtime_on_simple_date(runtime: Runtime) {
    let registry = test_utils::get_simple_registry().unwrap();
    let dir = tempdir().unwrap();
    let header_path = dir.path().join("test.hpp");
    let mut header = File::create(&header_path).unwrap();

    let config =
        CodeGeneratorConfig::new("testing".to_string()).with_encodings(vec![runtime.into()]);
    let generator = cpp::CodeGenerator::new(&config);
    generator.output(&mut header, &registry).unwrap();

    let reference = runtime.serialize(&Test {
        a: vec![4, 6],
        b: (-3, 5),
        c: Choice::C { x: 7 },
    });

    let source_path = dir.path().join("test.cpp");
    let mut source = File::create(&source_path).unwrap();
    writeln!(
        source,
        r#"
#include <cassert>
#include "test.hpp"

using namespace testing;

int main() {{
    std::vector<uint8_t> input = {{{0}}};
    auto test = Test::{1}Deserialize(input);

    auto a = std::vector<uint32_t> {{4, 6}};
    auto b = std::tuple<int64_t, uint64_t> {{-3, 5}};
    auto c = Choice {{ Choice::C {{ 7 }} }};
    auto test2 = Test {{a, b, c}};

    assert(test == test2);

    auto output = test2.{1}Serialize();

    assert(input == output);

    input.push_back(1);
    try {{
        Test::{1}Deserialize(input);
    }} catch (...) {{
        return 0;
    }}
    return 1;
}}
"#,
        reference
            .iter()
            .map(|x| format!("0x{:02x}", x))
            .collect::<Vec<_>>()
            .join(", "),
        runtime.name(),
    )
    .unwrap();

    let status = Command::new("clang++")
        .arg("--std=c++17")
        .arg("-o")
        .arg(dir.path().join("test"))
        .arg("-I")
        .arg("runtime/cpp")
        .arg(source_path)
        .status()
        .unwrap();
    assert!(status.success());

    let status = Command::new(dir.path().join("test")).status().unwrap();
    assert!(status.success());
}

#[test]
fn test_cpp_lcs_runtime_on_supported_types() {
    test_cpp_runtime_on_supported_types(Runtime::Lcs);
}

#[test]
fn test_cpp_bincode_runtime_on_supported_types() {
    test_cpp_runtime_on_supported_types(Runtime::Bincode);
}

fn test_cpp_runtime_on_supported_types(runtime: Runtime) {
    let registry = test_utils::get_registry().unwrap();
    let dir = tempdir().unwrap();
    let header_path = dir.path().join("test.hpp");
    let mut header = File::create(&header_path).unwrap();

    let config =
        CodeGeneratorConfig::new("testing".to_string()).with_encodings(vec![runtime.into()]);
    let generator = cpp::CodeGenerator::new(&config);
    generator.output(&mut header, &registry).unwrap();

    let values = test_utils::get_sample_values(runtime.has_canonical_maps());
    let encodings = values
        .iter()
        .map(|v| {
            let bytes = runtime.serialize(&v);
            format!(
                "std::vector<uint8_t>{{{}}}",
                bytes
                    .iter()
                    .map(|x| format!("0x{:02x}", x))
                    .collect::<Vec<_>>()
                    .join(", ")
            )
        })
        .collect::<Vec<_>>()
        .join(", ");

    let source_path = dir.path().join("test.cpp");
    let mut source = File::create(&source_path).unwrap();
    writeln!(
        source,
        r#"
#include <exception>
#include <iostream>
#include <cassert>
#include "test.hpp"

using namespace testing;

int main() {{
    try {{
        std::vector<std::vector<uint8_t>> inputs = {{{0}}};

        for (auto input: inputs) {{
            auto test = SerdeData::{1}Deserialize(input);
            auto output = test.{1}Serialize();
            assert(input == output);

            // Test simple mutations of the input.
            for (int i = 0; i < input.size(); i++) {{
                auto input2 = input;
                input2[i] ^= 0x80;
                try {{
                    auto test2 = SerdeData::{1}Deserialize(input2);
                    assert(!(test2 == test));
                }} catch (serde::deserialization_error e) {{
                    // All good
                }} catch (std::bad_alloc const &e) {{
                    // All good
                }} catch (std::length_error const &e) {{
                    // All good
                }}
            }}
        }}
        return 0;
    }} catch (std::exception& e) {{
        std::cout << "Error: " << e.what() << '\n';
        return 1;
    }}
}}
"#,
        encodings,
        runtime.name(),
    )
    .unwrap();

    let status = Command::new("clang++")
        .arg("--std=c++17")
        .arg("-g")
        .arg("-o")
        .arg(dir.path().join("test"))
        .arg("-I")
        .arg("runtime/cpp")
        .arg(source_path)
        .status()
        .unwrap();
    assert!(status.success());

    // Use `.status()` instead of `.output()` to debug error outputs.
    let output = Command::new(dir.path().join("test")).output().unwrap();
    assert!(output.status.success());
}
<|endoftext|>


<commit_before>use rustless;
use rustless::errors;
use rustless::prelude::*;
use rustless::server::status;
use jsonway;
use rustc_serialize::json::ToJson;

mod tweets;

pub fn root() -> rustless::Api {
    rustless::Api::build(|api| {
        api.prefix("api");
        api.version("v1", rustless::Versioning::Path);

        // Add error formatter to send validation errors back to the client
        api.error_formatter(|error, _media| {
            if error.is::<errors::Validation>() {
                let val_err = error.downcast::<errors::Validation>().unwrap();
                return Some(rustless::Response::from_json(status::StatusCode::Ok, &jsonway::object(|json| {
                    json.set_json("errors", val_err.reason.to_json())
                }).unwrap()))
            }

            None
        });

        api.mount(tweets::tweets("tweets"));
    })
}<commit_msg>fix(examples): use BadRequest in postgres example<commit_after>use rustless;
use rustless::errors;
use rustless::prelude::*;
use rustless::server::status;
use jsonway;
use rustc_serialize::json::ToJson;

mod tweets;

pub fn root() -> rustless::Api {
    rustless::Api::build(|api| {
        api.prefix("api");
        api.version("v1", rustless::Versioning::Path);

        // Add error formatter to send validation errors back to the client
        api.error_formatter(|error, _media| {
            if error.is::<errors::Validation>() {
                let val_err = error.downcast::<errors::Validation>().unwrap();
                return Some(rustless::Response::from_json(status::StatusCode::BadRequest, &jsonway::object(|json| {
                    json.set_json("errors", val_err.reason.to_json())
                }).unwrap()))
            }

            None
        });

        api.mount(tweets::tweets("tweets"));
    })
}
<|endoftext|>


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

#[test]
fn test_empty() {
    let expected: HashMap<u32, u32> = HashMap::new();
    let computed: HashMap<u32, u32> = hashmap!();
    assert_eq!(computed, expected);
}

#[test]
#[ignore]
fn test_no_trailing_comma() {
    let mut expected = HashMap::new();
    expected.insert(1, "one");
    expected.insert(2, "two");
    assert_eq!(hashmap!(1 => "one", 2 => "two"), expected);
}

#[test]
#[ignore]
fn test_trailing_comma() {
    let mut expected = HashMap::new();
    expected.insert('h', 89);
    expected.insert('a', 1);
    expected.insert('s', 19);
    expected.insert('h', 8);
    assert_eq!(
        hashmap!(
            'h' => 89,
            'a' => 1,
            's' => 19,
            'h' => 8,
        ),
        expected
    );
}

#[test]
#[ignore]
fn test_nested() {
    let mut expected = HashMap::new();
    expected.insert("non-empty", {
        let mut subhashmap = HashMap::new();
        subhashmap.insert(23, 623);
        subhashmap.insert(34, 21);
        subhashmap
    });
    expected.insert("empty", HashMap::new());
    assert_eq!(
        hashmap!(
            "non-empty" => hashmap!(
                23 => 623,
                34 => 21
            ),
            "empty" => hashmap!()
        ),
        expected
    );
}

mod test {
    use macros::hashmap;
    #[test]
    #[ignore]
    fn type_not_in_scope() {
        let _expected: ::std::collections::HashMap<(), ()> = hashmap!();
    }
}
<commit_msg>Add test for single macro argument<commit_after>use macros::hashmap;
use std::collections::HashMap;

#[test]
fn test_empty() {
    let expected: HashMap<u32, u32> = HashMap::new();
    let computed: HashMap<u32, u32> = hashmap!();
    assert_eq!(computed, expected);
}

#[test]
#[ignore]
fn test_single() {
    let mut expected = HashMap::new();
    expected.insert(1, "one");
    assert_eq!(hashmap!(1 => "one"), expected);
}

#[test]
#[ignore]
fn test_no_trailing_comma() {
    let mut expected = HashMap::new();
    expected.insert(1, "one");
    expected.insert(2, "two");
    assert_eq!(hashmap!(1 => "one", 2 => "two"), expected);
}

#[test]
#[ignore]
fn test_trailing_comma() {
    let mut expected = HashMap::new();
    expected.insert('h', 89);
    expected.insert('a', 1);
    expected.insert('s', 19);
    expected.insert('h', 8);
    assert_eq!(
        hashmap!(
            'h' => 89,
            'a' => 1,
            's' => 19,
            'h' => 8,
        ),
        expected
    );
}

#[test]
#[ignore]
fn test_nested() {
    let mut expected = HashMap::new();
    expected.insert("non-empty", {
        let mut subhashmap = HashMap::new();
        subhashmap.insert(23, 623);
        subhashmap.insert(34, 21);
        subhashmap
    });
    expected.insert("empty", HashMap::new());
    assert_eq!(
        hashmap!(
            "non-empty" => hashmap!(
                23 => 623,
                34 => 21
            ),
            "empty" => hashmap!()
        ),
        expected
    );
}

mod test {
    use macros::hashmap;
    #[test]
    #[ignore]
    fn type_not_in_scope() {
        let _expected: ::std::collections::HashMap<(), ()> = hashmap!();
    }
}
<|endoftext|>


<commit_before>use prolog::ast::*;
use prolog::codegen::*;
use prolog::debray_allocator::*;
use prolog::machine::*;

use termion::raw::IntoRawMode;
use termion::input::TermRead;
use termion::event::Key;

use std::io::{Write, stdin, stdout};
use std::fmt;

impl fmt::Display for Constant {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Constant::Atom(ref atom) =>
                write!(f, "{}", atom),
            &Constant::EmptyList =>
                write!(f, "[]")
        }
    }
}

impl fmt::Display for FactInstruction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &FactInstruction::GetConstant(Level::Shallow, ref constant, ref r) =>
                write!(f, "get_constant {}, A{}", constant, r.reg_num()),
            &FactInstruction::GetConstant(Level::Deep, ref constant, ref r) =>
                write!(f, "get_constant {}, {}", constant, r),
            &FactInstruction::GetList(Level::Shallow, ref r) =>
                write!(f, "get_list A{}", r.reg_num()),
            &FactInstruction::GetList(Level::Deep, ref r) =>
                write!(f, "get_list {}", r),
            &FactInstruction::GetStructure(Level::Deep, ref name, ref arity, ref r) =>
                write!(f, "get_structure {}/{}, {}", name, arity, r),
            &FactInstruction::GetStructure(Level::Shallow, ref name, ref arity, ref r) =>
                write!(f, "get_structure {}/{}, A{}", name, arity, r.reg_num()),
            &FactInstruction::GetValue(ref x, ref a) =>
                write!(f, "get_value {}, A{}", x, a),
            &FactInstruction::GetVariable(ref x, ref a) =>
                write!(f, "get_variable {}, A{}", x, a),
            &FactInstruction::UnifyConstant(ref constant) =>
                write!(f, "unify_constant {}", constant),
            &FactInstruction::UnifyVariable(ref r) =>
                write!(f, "unify_variable {}", r),
            &FactInstruction::UnifyLocalValue(ref r) =>
                write!(f, "unify_local_value {}", r),
            &FactInstruction::UnifyValue(ref r) =>
                write!(f, "unify_value {}", r),
            &FactInstruction::UnifyVoid(n) =>
                write!(f, "unify_void {}", n)
        }
    }
}

impl fmt::Display for QueryInstruction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &QueryInstruction::GetVariable(ref x, ref a) =>
                write!(f, "get_variable {}, A{}", x, a),
            &QueryInstruction::PutConstant(Level::Shallow, ref constant, ref r) =>
                write!(f, "put_constant {}, A{}", constant, r.reg_num()),
            &QueryInstruction::PutConstant(Level::Deep, ref constant, ref r) =>
                write!(f, "put_constant {}, {}", constant, r),
            &QueryInstruction::PutList(Level::Shallow, ref r) =>
                write!(f, "put_list A{}", r.reg_num()),
            &QueryInstruction::PutList(Level::Deep, ref r) =>
                write!(f, "put_list {}", r),
            &QueryInstruction::PutStructure(Level::Deep, ref name, ref arity, ref r) =>
                write!(f, "put_structure {}/{}, {}", name, arity, r),
            &QueryInstruction::PutStructure(Level::Shallow, ref name, ref arity, ref r) =>
                write!(f, "put_structure {}/{}, A{}", name, arity, r.reg_num()),
            &QueryInstruction::PutUnsafeValue(y, a) =>
                write!(f, "put_unsafe_value Y{}, A{}", y, a),
            &QueryInstruction::PutValue(ref x, ref a) =>
                write!(f, "put_value {}, A{}", x, a),
            &QueryInstruction::PutVariable(ref x, ref a) =>
                write!(f, "put_variable {}, A{}", x, a),
            &QueryInstruction::SetConstant(ref constant) =>
                write!(f, "set_constant {}", constant),
            &QueryInstruction::SetLocalValue(ref r) =>
                write!(f, "set_local_value {}", r),
            &QueryInstruction::SetVariable(ref r) =>
                write!(f, "set_variable {}", r),
            &QueryInstruction::SetValue(ref r) =>
                write!(f, "set_value {}", r),
            &QueryInstruction::SetVoid(n) =>
                write!(f, "set_void {}", n)
        }
    }
}

impl fmt::Display for ControlInstruction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &ControlInstruction::Allocate(num_cells) =>
                write!(f, "allocate {}", num_cells),
            &ControlInstruction::Call(ref name, arity, pvs) =>
                write!(f, "call {}/{}, {}", name, arity, pvs),
            &ControlInstruction::CallN(arity) =>
                write!(f, "call_N {}", arity),
            &ControlInstruction::ExecuteN(arity) =>
                write!(f, "execute_N {}", arity),
            &ControlInstruction::Deallocate =>
                write!(f, "deallocate"),
            &ControlInstruction::Execute(ref name, arity) =>
                write!(f, "execute {}/{}", name, arity),
            &ControlInstruction::Proceed =>
                write!(f, "proceed")
        }
    }
}

impl fmt::Display for IndexedChoiceInstruction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &IndexedChoiceInstruction::Try(offset) =>
                write!(f, "try {}", offset),
            &IndexedChoiceInstruction::Retry(offset) =>
                write!(f, "retry {}", offset),
            &IndexedChoiceInstruction::Trust(offset) =>
                write!(f, "trust {}", offset)
        }
    }
}

impl fmt::Display for ChoiceInstruction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &ChoiceInstruction::TryMeElse(offset) =>
                write!(f, "try_me_else {}", offset),
            &ChoiceInstruction::RetryMeElse(offset) =>
                write!(f, "retry_me_else {}", offset),
            &ChoiceInstruction::TrustMe =>
                write!(f, "trust_me")
        }
    }
}

impl fmt::Display for IndexingInstruction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &IndexingInstruction::SwitchOnTerm(v, c, l, s) =>
                write!(f, "switch_on_term {}, {}, {}, {}", v, c, l, s),
            &IndexingInstruction::SwitchOnConstant(num_cs, _) =>
                write!(f, "switch_on_constant {}", num_cs),
            &IndexingInstruction::SwitchOnStructure(num_ss, _) =>
                write!(f, "switch_on_structure {}", num_ss)
        }
    }
}

impl fmt::Display for CutInstruction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &CutInstruction::Cut(_) =>
                write!(f, "cut"),
            &CutInstruction::NeckCut(_) =>
                write!(f, "neck_cut"),
            &CutInstruction::GetLevel =>
                write!(f, "get_level")
        }
    }
}

impl fmt::Display for Level {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Level::Shallow => write!(f, "A"),
            &Level::Deep => write!(f, "X")
        }
    }
}

impl fmt::Display for VarReg {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &VarReg::Norm(RegType::Perm(reg)) => write!(f, "Y{}", reg),
            &VarReg::Norm(RegType::Temp(reg)) => write!(f, "X{}", reg),
            &VarReg::ArgAndNorm(RegType::Perm(reg), arg) =>
                write!(f, "Y{} A{}", reg, arg),
            &VarReg::ArgAndNorm(RegType::Temp(reg), arg) =>
                write!(f, "X{} A{}", reg, arg)
        }
    }
}

impl fmt::Display for RegType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &RegType::Perm(val) => write!(f, "Y{}", val),
            &RegType::Temp(val) => write!(f, "X{}", val)
        }
    }
}

fn is_consistent(predicate: &Vec<PredicateClause>) -> bool {
    let name  = predicate.first().unwrap().name();
    let arity = predicate.first().unwrap().arity();

    for clause in predicate.iter().skip(1) {
        if !(name == clause.name() && arity == clause.arity()) {
            return false;
        }
    }

    true
}

#[allow(dead_code)]
pub fn print_code(code: &Code) {
    for clause in code {
        match clause {
            &Line::Fact(ref fact) =>
                for fact_instr in fact {
                    println!("{}", fact_instr);
                },
            &Line::Cut(ref cut) =>
                println!("{}", cut),
            &Line::Choice(ref choice) =>
                println!("{}", choice),
            &Line::Control(ref control) =>
                println!("{}", control),
            &Line::IndexedChoice(ref choice) =>
                println!("{}", choice),
            &Line::Indexing(ref indexing) =>
                println!("{}", indexing),
            &Line::Query(ref query) =>
                for query_instr in query {
                    println!("{}", query_instr);
                }
        }
    }
}

pub fn read() -> String {
    let _ = stdout().flush();

    let mut buffer = String::new();
    let mut result = String::new();

    let stdin = stdin();
    stdin.read_line(&mut buffer).unwrap();

    if &*buffer.trim() == ":{" {
        buffer.clear();

        stdin.read_line(&mut buffer).unwrap();

        while &*buffer.trim() != "}:" {
            result += buffer.as_str();
            buffer.clear();
            stdin.read_line(&mut buffer).unwrap();
        }
    } else {
        result = buffer;
    }

    result
}

pub fn eval<'a, 'b: 'a>(wam: &'a mut Machine, tl: &'b TopLevel) -> EvalSession<'b>
{
    match tl {
        &TopLevel::Predicate(ref clauses) => {
            let mut cg = CodeGenerator::<DebrayAllocator>::new();

            if is_consistent(clauses) {
                let compiled_pred = cg.compile_predicate(clauses);
                print_code(&compiled_pred);
                wam.add_predicate(clauses, compiled_pred);

                EvalSession::EntrySuccess
            } else {
                let msg = r"Error: predicate is inconsistent.
Each predicate must have the same name and arity.";

                println!("{}", msg);
                EvalSession::EntryFailure
            }
        },
        &TopLevel::Fact(ref fact) => {
            let mut cg = CodeGenerator::<DebrayAllocator>::new();

            let compiled_fact = cg.compile_fact(fact);
            print_code(&compiled_fact);
            wam.add_fact(fact, compiled_fact);

            EvalSession::EntrySuccess
        },
        &TopLevel::Rule(ref rule) => {
            let mut cg = CodeGenerator::<DebrayAllocator>::new();

            let compiled_rule = cg.compile_rule(rule);
            print_code(&compiled_rule);
            wam.add_rule(rule, compiled_rule);

            EvalSession::EntrySuccess
        },
        &TopLevel::Query(ref query) => {
            let mut cg = CodeGenerator::<DebrayAllocator>::new();

            let compiled_query = cg.compile_query(query);
            print_code(&compiled_query);
            wam.submit_query(compiled_query, cg.take_vars())
        }
    }
}

pub fn print(wam: &mut Machine, result: EvalSession) {
    match result {
        EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => {
            print!("true");

            if !wam.or_stack_is_empty() {
                print!(" ");
            }

            println!(".");

            if heap_locs.is_empty() {
                return;
            }

            loop {
                let mut result = EvalSession::QueryFailure;
                let bindings = wam.heap_view(&heap_locs);

                let stdin  = stdin();
                let mut stdout = stdout().into_raw_mode().unwrap();

                write!(stdout, "{}", bindings).unwrap();
                stdout.flush().unwrap();

                if !wam.or_stack_is_empty() {
                    stdout.flush().unwrap();

                    for c in stdin.keys() {
                        match c.unwrap() {
                            Key::Char(';') => {
                                write!(stdout, " ;\n\r").unwrap();
                                result = wam.continue_query(&alloc_locs, &mut heap_locs);
                                break;
                            },
                            Key::Char('.') => {
                                write!(stdout, " .\n\r").unwrap();
                                return;
                            },
                            _ => {}
                        }
                    }

                    if let &EvalSession::QueryFailure = &result {
                        write!(stdout, "false.\n\r").unwrap();
                        stdout.flush().unwrap();
                        return;
                    }
                } else {
                    break;
                }
            }

            write!(stdout(), ".\n").unwrap();
        },
        EvalSession::QueryFailure => println!("false."),
        _ => {}
    };
}
<commit_msg>remove diagnostic calls<commit_after>use prolog::ast::*;
use prolog::codegen::*;
use prolog::debray_allocator::*;
use prolog::machine::*;

use termion::raw::IntoRawMode;
use termion::input::TermRead;
use termion::event::Key;

use std::io::{Write, stdin, stdout};
use std::fmt;

impl fmt::Display for Constant {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Constant::Atom(ref atom) =>
                write!(f, "{}", atom),
            &Constant::EmptyList =>
                write!(f, "[]")
        }
    }
}

impl fmt::Display for FactInstruction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &FactInstruction::GetConstant(Level::Shallow, ref constant, ref r) =>
                write!(f, "get_constant {}, A{}", constant, r.reg_num()),
            &FactInstruction::GetConstant(Level::Deep, ref constant, ref r) =>
                write!(f, "get_constant {}, {}", constant, r),
            &FactInstruction::GetList(Level::Shallow, ref r) =>
                write!(f, "get_list A{}", r.reg_num()),
            &FactInstruction::GetList(Level::Deep, ref r) =>
                write!(f, "get_list {}", r),
            &FactInstruction::GetStructure(Level::Deep, ref name, ref arity, ref r) =>
                write!(f, "get_structure {}/{}, {}", name, arity, r),
            &FactInstruction::GetStructure(Level::Shallow, ref name, ref arity, ref r) =>
                write!(f, "get_structure {}/{}, A{}", name, arity, r.reg_num()),
            &FactInstruction::GetValue(ref x, ref a) =>
                write!(f, "get_value {}, A{}", x, a),
            &FactInstruction::GetVariable(ref x, ref a) =>
                write!(f, "get_variable {}, A{}", x, a),
            &FactInstruction::UnifyConstant(ref constant) =>
                write!(f, "unify_constant {}", constant),
            &FactInstruction::UnifyVariable(ref r) =>
                write!(f, "unify_variable {}", r),
            &FactInstruction::UnifyLocalValue(ref r) =>
                write!(f, "unify_local_value {}", r),
            &FactInstruction::UnifyValue(ref r) =>
                write!(f, "unify_value {}", r),
            &FactInstruction::UnifyVoid(n) =>
                write!(f, "unify_void {}", n)
        }
    }
}

impl fmt::Display for QueryInstruction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &QueryInstruction::GetVariable(ref x, ref a) =>
                write!(f, "get_variable {}, A{}", x, a),
            &QueryInstruction::PutConstant(Level::Shallow, ref constant, ref r) =>
                write!(f, "put_constant {}, A{}", constant, r.reg_num()),
            &QueryInstruction::PutConstant(Level::Deep, ref constant, ref r) =>
                write!(f, "put_constant {}, {}", constant, r),
            &QueryInstruction::PutList(Level::Shallow, ref r) =>
                write!(f, "put_list A{}", r.reg_num()),
            &QueryInstruction::PutList(Level::Deep, ref r) =>
                write!(f, "put_list {}", r),
            &QueryInstruction::PutStructure(Level::Deep, ref name, ref arity, ref r) =>
                write!(f, "put_structure {}/{}, {}", name, arity, r),
            &QueryInstruction::PutStructure(Level::Shallow, ref name, ref arity, ref r) =>
                write!(f, "put_structure {}/{}, A{}", name, arity, r.reg_num()),
            &QueryInstruction::PutUnsafeValue(y, a) =>
                write!(f, "put_unsafe_value Y{}, A{}", y, a),
            &QueryInstruction::PutValue(ref x, ref a) =>
                write!(f, "put_value {}, A{}", x, a),
            &QueryInstruction::PutVariable(ref x, ref a) =>
                write!(f, "put_variable {}, A{}", x, a),
            &QueryInstruction::SetConstant(ref constant) =>
                write!(f, "set_constant {}", constant),
            &QueryInstruction::SetLocalValue(ref r) =>
                write!(f, "set_local_value {}", r),
            &QueryInstruction::SetVariable(ref r) =>
                write!(f, "set_variable {}", r),
            &QueryInstruction::SetValue(ref r) =>
                write!(f, "set_value {}", r),
            &QueryInstruction::SetVoid(n) =>
                write!(f, "set_void {}", n)
        }
    }
}

impl fmt::Display for ControlInstruction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &ControlInstruction::Allocate(num_cells) =>
                write!(f, "allocate {}", num_cells),
            &ControlInstruction::Call(ref name, arity, pvs) =>
                write!(f, "call {}/{}, {}", name, arity, pvs),
            &ControlInstruction::CallN(arity) =>
                write!(f, "call_N {}", arity),
            &ControlInstruction::ExecuteN(arity) =>
                write!(f, "execute_N {}", arity),
            &ControlInstruction::Deallocate =>
                write!(f, "deallocate"),
            &ControlInstruction::Execute(ref name, arity) =>
                write!(f, "execute {}/{}", name, arity),
            &ControlInstruction::Proceed =>
                write!(f, "proceed")
        }
    }
}

impl fmt::Display for IndexedChoiceInstruction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &IndexedChoiceInstruction::Try(offset) =>
                write!(f, "try {}", offset),
            &IndexedChoiceInstruction::Retry(offset) =>
                write!(f, "retry {}", offset),
            &IndexedChoiceInstruction::Trust(offset) =>
                write!(f, "trust {}", offset)
        }
    }
}

impl fmt::Display for ChoiceInstruction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &ChoiceInstruction::TryMeElse(offset) =>
                write!(f, "try_me_else {}", offset),
            &ChoiceInstruction::RetryMeElse(offset) =>
                write!(f, "retry_me_else {}", offset),
            &ChoiceInstruction::TrustMe =>
                write!(f, "trust_me")
        }
    }
}

impl fmt::Display for IndexingInstruction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &IndexingInstruction::SwitchOnTerm(v, c, l, s) =>
                write!(f, "switch_on_term {}, {}, {}, {}", v, c, l, s),
            &IndexingInstruction::SwitchOnConstant(num_cs, _) =>
                write!(f, "switch_on_constant {}", num_cs),
            &IndexingInstruction::SwitchOnStructure(num_ss, _) =>
                write!(f, "switch_on_structure {}", num_ss)
        }
    }
}

impl fmt::Display for CutInstruction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &CutInstruction::Cut(_) =>
                write!(f, "cut"),
            &CutInstruction::NeckCut(_) =>
                write!(f, "neck_cut"),
            &CutInstruction::GetLevel =>
                write!(f, "get_level")
        }
    }
}

impl fmt::Display for Level {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Level::Shallow => write!(f, "A"),
            &Level::Deep => write!(f, "X")
        }
    }
}

impl fmt::Display for VarReg {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &VarReg::Norm(RegType::Perm(reg)) => write!(f, "Y{}", reg),
            &VarReg::Norm(RegType::Temp(reg)) => write!(f, "X{}", reg),
            &VarReg::ArgAndNorm(RegType::Perm(reg), arg) =>
                write!(f, "Y{} A{}", reg, arg),
            &VarReg::ArgAndNorm(RegType::Temp(reg), arg) =>
                write!(f, "X{} A{}", reg, arg)
        }
    }
}

impl fmt::Display for RegType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &RegType::Perm(val) => write!(f, "Y{}", val),
            &RegType::Temp(val) => write!(f, "X{}", val)
        }
    }
}

fn is_consistent(predicate: &Vec<PredicateClause>) -> bool {
    let name  = predicate.first().unwrap().name();
    let arity = predicate.first().unwrap().arity();

    for clause in predicate.iter().skip(1) {
        if !(name == clause.name() && arity == clause.arity()) {
            return false;
        }
    }

    true
}

#[allow(dead_code)]
pub fn print_code(code: &Code) {
    for clause in code {
        match clause {
            &Line::Fact(ref fact) =>
                for fact_instr in fact {
                    println!("{}", fact_instr);
                },
            &Line::Cut(ref cut) =>
                println!("{}", cut),
            &Line::Choice(ref choice) =>
                println!("{}", choice),
            &Line::Control(ref control) =>
                println!("{}", control),
            &Line::IndexedChoice(ref choice) =>
                println!("{}", choice),
            &Line::Indexing(ref indexing) =>
                println!("{}", indexing),
            &Line::Query(ref query) =>
                for query_instr in query {
                    println!("{}", query_instr);
                }
        }
    }
}

pub fn read() -> String {
    let _ = stdout().flush();

    let mut buffer = String::new();
    let mut result = String::new();

    let stdin = stdin();
    stdin.read_line(&mut buffer).unwrap();

    if &*buffer.trim() == ":{" {
        buffer.clear();

        stdin.read_line(&mut buffer).unwrap();

        while &*buffer.trim() != "}:" {
            result += buffer.as_str();
            buffer.clear();
            stdin.read_line(&mut buffer).unwrap();
        }
    } else {
        result = buffer;
    }

    result
}

pub fn eval<'a, 'b: 'a>(wam: &'a mut Machine, tl: &'b TopLevel) -> EvalSession<'b>
{
    match tl {
        &TopLevel::Predicate(ref clauses) => {
            let mut cg = CodeGenerator::<DebrayAllocator>::new();

            if is_consistent(clauses) {
                let compiled_pred = cg.compile_predicate(clauses);
                wam.add_predicate(clauses, compiled_pred);

                EvalSession::EntrySuccess
            } else {
                let msg = r"Error: predicate is inconsistent.
Each predicate must have the same name and arity.";

                println!("{}", msg);
                EvalSession::EntryFailure
            }
        },
        &TopLevel::Fact(ref fact) => {
            let mut cg = CodeGenerator::<DebrayAllocator>::new();

            let compiled_fact = cg.compile_fact(fact);
            wam.add_fact(fact, compiled_fact);

            EvalSession::EntrySuccess
        },
        &TopLevel::Rule(ref rule) => {
            let mut cg = CodeGenerator::<DebrayAllocator>::new();

            let compiled_rule = cg.compile_rule(rule);
            wam.add_rule(rule, compiled_rule);

            EvalSession::EntrySuccess
        },
        &TopLevel::Query(ref query) => {
            let mut cg = CodeGenerator::<DebrayAllocator>::new();

            let compiled_query = cg.compile_query(query);
            wam.submit_query(compiled_query, cg.take_vars())
        }
    }
}

pub fn print(wam: &mut Machine, result: EvalSession) {
    match result {
        EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => {
            print!("true");

            if !wam.or_stack_is_empty() {
                print!(" ");
            }

            println!(".");

            if heap_locs.is_empty() {
                return;
            }

            loop {
                let mut result = EvalSession::QueryFailure;
                let bindings = wam.heap_view(&heap_locs);

                let stdin  = stdin();
                let mut stdout = stdout().into_raw_mode().unwrap();

                write!(stdout, "{}", bindings).unwrap();
                stdout.flush().unwrap();

                if !wam.or_stack_is_empty() {
                    stdout.flush().unwrap();

                    for c in stdin.keys() {
                        match c.unwrap() {
                            Key::Char(';') => {
                                write!(stdout, " ;\n\r").unwrap();
                                result = wam.continue_query(&alloc_locs, &mut heap_locs);
                                break;
                            },
                            Key::Char('.') => {
                                write!(stdout, " .\n\r").unwrap();
                                return;
                            },
                            _ => {}
                        }
                    }

                    if let &EvalSession::QueryFailure = &result {
                        write!(stdout, "false.\n\r").unwrap();
                        stdout.flush().unwrap();
                        return;
                    }
                } else {
                    break;
                }
            }

            write!(stdout(), ".\n").unwrap();
        },
        EvalSession::QueryFailure => println!("false."),
        _ => {}
    };
}
<|endoftext|>


<commit_before>//
//  SOS: the Stupid Operating System
//  by Eliza Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2016-2017 Eliza Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! Initial 32-bit bootloader for x86_64
#![crate_name = "boot"]
// #![crate_type = "staticlib"]
#![feature(asm)]
#![feature(lang_items)]
#![feature(naked_functions)]
#![feature(static_recursion)]
#![feature(linkage)]
#![feature(struct_field_attributes)]
#![feature(stmt_expr_attributes)]
#![no_std]
// #![no_main]

const TABLE_LENGTH: usize = 512;

type Table = [u64; TABLE_LENGTH];

use core::ptr;

// #[lang = "panic_fmt"]
// #[cold]
// unsafe extern fn panic_fmt() -> ! {
//     let vga_buf: *mut u16 = 0xb8000 as *mut u16;
//     for (i, c) in b"boot panic occurred!".iter().enumerate() {
//         ptr::write_volatile( vga_buf.offset(i as isize)
//                            , 0x0200 + *c as u16);
//     }
//     loop { asm!("hlt") };
// }

#[repr(C, packed)]
pub struct Gdt { _null: u64
               , code: u64
            //    , data: u64
               , _pad: u16
               , pub ptr: GdtPointer
        //    , ptr: GdtPointer
           }

#[repr(C, packed)]
pub struct GdtPointer { /// the length of the descriptor table
                     pub limit: u16
                   , /// pointer to the region in memory
                     /// containing the descriptor table.
                     pub base: &'static Gdt
                   }

// TODO: this sucks please fix
#[link_name = ".gdt64"]
#[link_section = ".gdt"]
#[no_mangle]
pub static GDT: Gdt
    = Gdt { _null: 0
          , #[export_name = "gdt64.code"] #[no_mangle]
            code: (1<<44) | (1<<47) | (1<<41) | (1<<43) | (1<<53)
        //   , data: (1 << 44) | (1 << 47) | (1 << 41)
          , _pad: 0
          , ptr:
                #[no_mangle]
                GdtPointer { limit: 15
                            , base: &GDT
                            }
          };

// #[no_mangle]
// static mut GDT_PTR: GdtPointer
//     = GdtPointer { limit: 15
//                  , base: &GDT
//                  };

#[cfg(feature = "log")]
#[inline(always)]
#[naked]
fn boot_write(s: &[u8]) {
	// use core::ptr;
    let mut offset = 0;
    unsafe {
        let vga_buf: *mut u16 = 0xb8000 as *mut u16;
    	for c in s {
    		ptr::write_volatile( vga_buf.offset(offset)
                               , 0x0200 + *c as u16);
    		offset += 1;
    	}

    }

}

#[cfg(not(feature = "log"))]
fn boot_write(_s: &[u8]) { }

extern "C" {
    static mut pml4_table: Table;
    static mut pdp_table: Table;
    static mut pd_table: Table;    // static mut page_table: Table;
}

// #[naked]
// #[inline(always)]
// unsafe fn set_cs(cs: u16) {
//     asm!("ljmpl $0, $$fake_label
//           fake_label: \n\t"
//         :
//         : "i"(cs)
//         : "ax"
//         : "volatile"
//         );
// }

#[naked]
unsafe fn create_page_tables() {
    // 3. if everything is okay, create the page tables and start long mode
    const HUGE_PAGE_SIZE: u64 = 2 * 1024 * 1024; // 2 MiB

    //-- map the PML4 and PDP tables -----------------------------------------
    // recursive map last PML4 entry
    pml4_table[511] = (&pml4_table as *const _ as u64) | 0b11;
    // map first PML4 entry to PDP table
    pml4_table[0] = (&pdp_table as *const _ as u64) | 0b11;
    // map first PDPT entry to PD table
    pdp_table[0] = (&pd_table as *const _ as u64) | 0b11;

    boot_write(b"3.1");

    //-- map the PD table ----------------------------------------------------
    for (number, entry) in pd_table.iter_mut().enumerate() {
        // set each PD entry equal to the start address of the page (the page
        // number times the page's size)
        let addr = number as u64 * HUGE_PAGE_SIZE;
        // with the appropriate flags (present + writable + huge)
        // TODO: do we want to do this using bitflags, or is that too
        //       heavyweight for the boot module?
        //          - eliza, 1/23/2017
        *entry = addr | 0b10000011;
    }

    boot_write(b"3.2");
}

#[naked]
unsafe fn set_long_mode() {

    // load PML4 addr to cr3
    asm!( "mov   cr3, $0" :: "r"(&pml4_table) :: "intel");
    boot_write(b"3.3");

    // enable PAE flag in cr4
    let mut cr4: usize;
    asm!("mov $0, cr4" : "=r"(cr4) ::: "intel");
    cr4 |= 1 << 5;
    asm!("mov cr4, $0" :: "r"(cr4) :: "intel");
    boot_write(b"3.4");

    // set the long mode bit in EFER MSR (model specific register)
    asm!( "mov   ecx, 0xC0000080
           rdmsr
           or    eax, 1 << 8
           wrmsr"
        :::: "intel");
    boot_write(b"3.5");

    // enable paging in cr0
    // let mut cr0: usize;
    // asm!( "mov $0, cr0" : "=r"(cr0) ::: "intel");
    // cr0 |= 1 << 31;
    // cr0 |= 1 << 16;
    // asm!( "mov cr0, $0" :: "r"(cr0) :: "intel");
    // boot_write(b"3.6");
    asm!( "mov eax, cr0
           or  eax, 1 << 31
           or  eax, 1 << 16
           mov cr0, eax"
        :::: "intel");
}

#[cold]
#[no_mangle]
#[naked]
pub unsafe extern "C" fn _start() {
    // 0. Move the stack pointer to the top of the stack.
    asm!( "mov esp, stack_top" :::: "intel" );
    boot_write(b"0");
    asm!("cli");

    // 1. Move Multiboot info pointer to edi
    // let multiboot: usize;
    asm!("mov edi, edx"
         : //"=r"(multiboot)
         ::: "intel"
    );
    boot_write(b"1");

    // 2. make sure the system supports SOS
    // TODO: port this from boot.asm
    boot_write(b"2");

    create_page_tables();
    set_long_mode();

    // 4. load the 64-bit GDT
    asm!("lgdt ($0)" :: "r"(&GDT.ptr) : "memory" );
    boot_write(b"4");

    // // 5. update selectors
    // asm!("mov ax, 0x10" :::: "intel");
    // boot_write(b"5.1");
    // // stack selector
    // asm!("mov ss, ax" :::: "intel");
    // boot_write(b"5.2");
    // // data selector
    // asm!("mov ds, ax" :::: "intel");
    // boot_write(b"5.3");
    // // extra selector
    // asm!("mov es, ax" :::: "intel");
    // boot_write(b"5.4");

    // 6. jump to the 64-bit boot subroutine.
    asm!( "ljmpl $$8, $$arch_init" );

}
<commit_msg>[boot] make GDT pointer much rustier<commit_after>//
//  SOS: the Stupid Operating System
//  by Eliza Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2016-2017 Eliza Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! Initial 32-bit bootloader for x86_64
#![crate_name = "boot"]
// #![crate_type = "staticlib"]
#![feature(asm)]
#![feature(lang_items)]
#![feature(naked_functions)]
#![feature(static_recursion)]
#![feature(linkage)]
#![feature(struct_field_attributes)]
#![feature(stmt_expr_attributes)]
#![no_std]
// #![no_main]

const TABLE_LENGTH: usize = 512;

type Table = [u64; TABLE_LENGTH];

use core::ptr;

// #[lang = "panic_fmt"]
// #[cold]
// unsafe extern fn panic_fmt() -> ! {
//     let vga_buf: *mut u16 = 0xb8000 as *mut u16;
//     for (i, c) in b"boot panic occurred!".iter().enumerate() {
//         ptr::write_volatile( vga_buf.offset(i as isize)
//                            , 0x0200 + *c as u16);
//     }
//     loop { asm!("hlt") };
// }

#[repr(C, packed)]
pub struct Gdt { _null: u64
               , code: u64
               }

#[repr(C, packed)]
pub struct GdtPointer { /// the length of the GDT
                        pub limit: u16
                      , /// pointer to the GDT
                        pub base: &'static Gdt
                      }

impl GdtPointer {
    #[inline]
    unsafe fn load (&self) {
        asm!("lgdt $0" :: "m"(self) : "memory");
    }
}

#[link_name = ".gdt64"]
#[link_section = ".gdt"]
#[no_mangle]
pub static GDT: Gdt
    = Gdt { _null: 0
          , code: (1<<44) | (1<<47) | (1<<41) | (1<<43) | (1<<53)
        //   , data: (1 << 44) | (1 << 47) | (1 << 41)
          };

// #[no_mangle]
// static mut GDT_PTR: GdtPointer
//     = GdtPointer { limit: 15
//                  , base: &GDT
//                  };

#[cfg(feature = "log")]
#[inline(always)]
#[naked]
fn boot_write(s: &[u8]) {
	// use core::ptr;
    let mut offset = 0;
    unsafe {
        let vga_buf: *mut u16 = 0xb8000 as *mut u16;
    	for c in s {
    		ptr::write_volatile( vga_buf.offset(offset)
                               , 0x0200 + *c as u16);
    		offset += 1;
    	}

    }

}

#[cfg(not(feature = "log"))]
fn boot_write(_s: &[u8]) { }

extern "C" {
    static mut pml4_table: Table;
    static mut pdp_table: Table;
    static mut pd_table: Table;    // static mut page_table: Table;
}

// #[naked]
// #[inline(always)]
// unsafe fn set_cs(cs: u16) {
//     asm!("ljmpl $0, $$fake_label
//           fake_label: \n\t"
//         :
//         : "i"(cs)
//         : "ax"
//         : "volatile"
//         );
// }

#[naked]
unsafe fn create_page_tables() {
    // 3. if everything is okay, create the page tables and start long mode
    const HUGE_PAGE_SIZE: u64 = 2 * 1024 * 1024; // 2 MiB

    //-- map the PML4 and PDP tables -----------------------------------------
    // recursive map last PML4 entry
    pml4_table[511] = (&pml4_table as *const _ as u64) | 0b11;
    // map first PML4 entry to PDP table
    pml4_table[0] = (&pdp_table as *const _ as u64) | 0b11;
    // map first PDPT entry to PD table
    pdp_table[0] = (&pd_table as *const _ as u64) | 0b11;

    boot_write(b"3.1");

    //-- map the PD table ----------------------------------------------------
    for (number, entry) in pd_table.iter_mut().enumerate() {
        // set each PD entry equal to the start address of the page (the page
        // number times the page's size)
        let addr = number as u64 * HUGE_PAGE_SIZE;
        // with the appropriate flags (present + writable + huge)
        // TODO: do we want to do this using bitflags, or is that too
        //       heavyweight for the boot module?
        //          - eliza, 1/23/2017
        *entry = addr | 0b10000011;
    }

    boot_write(b"3.2");
}

#[naked]
unsafe fn set_long_mode() {

    // load PML4 addr to cr3
    asm!( "mov   cr3, $0" :: "r"(&pml4_table) :: "intel");
    boot_write(b"3.3");

    // enable PAE flag in cr4
    let mut cr4: usize;
    asm!("mov $0, cr4" : "=r"(cr4) ::: "intel");
    cr4 |= 1 << 5;
    asm!("mov cr4, $0" :: "r"(cr4) :: "intel");
    boot_write(b"3.4");

    // set the long mode bit in EFER MSR (model specific register)
    asm!( "mov   ecx, 0xC0000080
           rdmsr
           or    eax, 1 << 8
           wrmsr"
        :::: "intel");
    boot_write(b"3.5");

    // enable paging in cr0
    // let mut cr0: usize;
    // asm!( "mov $0, cr0" : "=r"(cr0) ::: "intel");
    // cr0 |= 1 << 31;
    // cr0 |= 1 << 16;
    // asm!( "mov cr0, $0" :: "r"(cr0) :: "intel");
    // boot_write(b"3.6");
    asm!( "mov eax, cr0
           or  eax, 1 << 31
           or  eax, 1 << 16
           mov cr0, eax"
        :::: "intel");
}

#[cold]
#[no_mangle]
#[naked]
pub unsafe extern "C" fn _start() {
    use core::mem;
    // 0. Move the stack pointer to the top of the stack.
    asm!( "mov esp, stack_top" :::: "intel" );
    boot_write(b"0");
    asm!("cli");

    // 1. Move Multiboot info pointer to edi
    // let multiboot: usize;
    asm!("mov edi, edx"
         : //"=r"(multiboot)
         ::: "intel"
    );
    boot_write(b"1");

    // 2. make sure the system supports SOS
    // TODO: port this from boot.asm
    boot_write(b"2");

    create_page_tables();
    set_long_mode();

    // 4. load the 64-bit GDT
    let gdt_ptr = GdtPointer { limit: mem::size_of_val(&GDT) as u16 - 1
                             , base: &GDT };

    // asm!("lgdt ($0)" :: "r"(&gdt_ptr) : "memory" );
    gdt_ptr.load();
    boot_write(b"4");

    // // 5. update selectors
    // asm!("mov ax, 0x10" :::: "intel");
    // boot_write(b"5.1");
    // // stack selector
    // asm!("mov ss, ax" :::: "intel");
    // boot_write(b"5.2");
    // // data selector
    // asm!("mov ds, ax" :::: "intel");
    // boot_write(b"5.3");
    // // extra selector
    // asm!("mov es, ax" :::: "intel");
    // boot_write(b"5.4");

    // 6. jump to the 64-bit boot subroutine.
    asm!( "ljmpl $$8, $$arch_init" );

}
<|endoftext|>