<commit_before>use time::now_utc;
use std::io::{File, Open, ReadWrite};

pub fn gen_timecode() -> String {
    now_utc().strftime("%Y%m%d%H%M%S").unwrap()
}

pub fn gen_full_name(name: &str) -> String {
    format!("_{}_{}", gen_timecode(), name)
}

pub fn create_migration_file(name: &str, base_path: Path) -> String {
    let full_name = gen_full_name(name);
    let final_path = base_path.join(format!("{}.rs", full_name));

    let mut file = match File::open_mode(&final_path, Open, ReadWrite) {
        Ok(f) => f,
        Err(e) => panic!("file error: {}", e),
    };

    file.write(b"").unwrap();
    full_name
}<commit_msg>feat: add more stuff about Pg migrations<commit_after>use time::now_utc;
use std::io::{File, Open, ReadWrite};
use postgres::Connection;
use std::collections::hash_map::HashMap;

pub fn gen_timecode() -> String {
    now_utc().strftime("%y%m%d%H%M%S").unwrap()
}

pub fn gen_full_name(name: &str) -> String {
    format!("_{}_{}", gen_timecode(), name)
}

pub fn create_migration_file(name: &str, base_path: Path) -> String {
    let full_name = gen_full_name(name);
    let final_path = base_path.join(format!("{}.rs", full_name));

    let mut file = match File::open_mode(&final_path, Open, ReadWrite) {
        Ok(f) => f,
        Err(e) => panic!("file error: {}", e),
    };

    file.write(b"").unwrap();
    full_name
}

pub trait RawMigration<Conn> {
    fn version(&self) -> u64;
    fn up(&self, cn: &Conn);
    fn down(&self, cn: &Conn);
}

pub type Migrations = Vec<Box<RawMigration<Connection> + 'static>>;
pub type MigrationRefs<'a> = Vec<&'a Box<RawMigration<Connection> + 'static>>;

pub fn ensure_schema_migrations(cn: &Connection) {
    cn.execute("CREATE TABLE IF NOT EXISTS schema_migrations (
         version BIGINT NOT NULL
    );", &[]).unwrap();
}

pub fn insert_version(version: &i64, cn: &Connection) {
    cn.execute("INSERT INTO schema_migrations VALUES ($1);", &[version]).unwrap();
}

pub fn delete_version(version: &i64, cn: &Connection) {
    cn.execute("DELETE FROM schema_migrations WHERE version = $1;", &[version]).unwrap();
}

pub fn get_versions_as_hash(cn: &Connection) -> HashMap<i64, bool> {
    let stmt = cn.prepare("SELECT version FROM schema_migrations ORDER BY version desc;").unwrap();
    let mut rows = stmt.query(&[]).unwrap();
    let mut db_versions: HashMap<i64, bool> = HashMap::new();

    for row in rows {
        db_versions.insert(row.get(0), true);
    }

    db_versions
}

pub fn get_versions_as_vec(cn: &Connection) -> Vec<i64> {
    let stmt = cn.prepare("SELECT version FROM schema_migrations ORDER BY version desc;").unwrap();
    let mut rows = stmt.query(&[]).unwrap();
    let mut db_versions: Vec<i64> = vec![];

    for row in rows {
        db_versions.push(row.get(0));
    }

    db_versions
}

pub fn run(migrations: &Migrations, cn: &Connection) {
    ensure_schema_migrations(cn);
    let db_versions = get_versions_as_hash(cn);

    let migrations_to_run: MigrationRefs = migrations.iter().filter(|m| {
        let version = m.version().to_i64().unwrap();
        !db_versions.contains_key(&version)
    }).collect();

    for migration in migrations_to_run.iter() {
        migration.up(cn);
        insert_version(&migration.version().to_i64().unwrap(), cn);

        println!("Migration completed: {}", migration.version());
    }
}

pub fn rollback(steps: uint, migrations: &Migrations, cn: &Connection) {
    ensure_schema_migrations(cn);
    let db_versions = get_versions_as_vec(cn);
    let db_versions_to_run = db_versions.slice(0, steps);

    let migrations_to_run: MigrationRefs = migrations.iter().filter(|m| {
        let version = m.version().to_i64().unwrap();
        db_versions_to_run.contains(&version)
    }).collect();

    for migration in migrations_to_run.iter() {
        migration.down(cn);
        delete_version(&migration.version().to_i64().unwrap(), cn);

        println!("Migration reverted: {}", migration.version());
    }
}<|endoftext|>


<commit_before>use neat::*;

#[derive(Debug, Clone)]
pub struct Organism {
    pub genome: Genome,
    pub fitness: f64,
    pub neurons: Vec<Option<Neuron>>
}

const ACTIVATION_CYCLES: usize = 5;

impl Organism {
    pub fn new(genome: Genome) -> Organism {
        Organism { genome: genome, fitness: 0f64, neurons: vec![] }
    }

    pub fn mutate(&mut self) {
        self.genome.mutate();
    }

    pub fn mate(&self, other: &Organism) -> Organism {
       Organism::new(self.genome.mate(&other.genome))
    }

    pub fn activate(&mut self, sensors: &Vec<f64>, outputs: &mut Vec<f64>){
       if self.neurons.len() == 0 {
           self.generate_phenome();
       };

       for neuron_id in 0..sensors.len() {
           if neuron_id < self.neurons.len() {
               self.neurons[neuron_id].as_mut().unwrap().stimulate(sensors[neuron_id]);
           }
       }

       for _n in 0..ACTIVATION_CYCLES {
           self.activate_neurons(sensors.len(), outputs.len());
           self.propagate_signals();
       }

       //Take outputs from next neurons after sensors
       for neuron_id in sensors.len()..(sensors.len() + outputs.len()){
           if neuron_id < self.neurons.len() {
               outputs[neuron_id - sensors.len()] = self.neurons[neuron_id].as_ref().map_or(0f64, |neuron| neuron.stimulation());
           } else {
               outputs[neuron_id - sensors.len()] = 0f64;
           }
       }
    }

    fn activate_neurons(&mut self, sensor_neurons_size: usize, output_neurons_size: usize){
        //Don't reset sensor neurons during activation
        for neuron_id in 0..sensor_neurons_size {
            self.neurons[neuron_id].as_mut().unwrap().shot(true);
        }

        for neuron_id in sensor_neurons_size..self.neurons.len() {
            self.neurons[neuron_id].as_mut().unwrap().shot(false);
        }
    }

    fn propagate_signals(&mut self){
        for neuron_option in self.neurons.clone() {
            let neuron = neuron_option.unwrap();
            for connection in &neuron.connections {
               self.neurons[connection.0].as_mut().unwrap().stimulate(neuron.potential() * connection.1);
            }
        }
    }

    fn generate_phenome(&mut self){
        let neurons_to_generate = self.genome.len();

        self.neurons = vec![None; neurons_to_generate as usize];

        for gene in self.genome.get_genes() {
            if self.neurons[gene.in_neuron_id].is_none(){
                self.neurons[gene.in_neuron_id] = Some(Neuron::new())
            }

            if self.neurons[gene.out_neuron_id].is_none(){
                self.neurons[gene.out_neuron_id] = Some(Neuron::new())
            }

            let mut neuron = self.neurons[gene.in_neuron_id].as_mut().unwrap();
            neuron.connections.push(Connection(gene.out_neuron_id, gene.weight));
        }
    }
}

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

    #[test]
    fn should_be_able_to_generate_his_phenome(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 0, 0.1f64);
        organism.genome.inject_gene(0, 1, 0.2f64);
        organism.genome.inject_gene(1, 1, 0.3f64);
        organism.genome.inject_gene(1, 0, 0.4f64);
        organism.generate_phenome();
        assert!(organism.neurons.len() == 2);
        let neuron0 = &organism.neurons[0].as_ref().unwrap();
        let connection00 = &neuron0.connections[0];
        assert!(connection00.0 == 0usize);
        assert!(connection00.1 == 0.1f64);
        let connection01 = &neuron0.connections[1];
        assert!(connection01.0 == 1usize);
        assert!(connection01.1 == 0.2f64);
        let neuron1 = &organism.neurons[1].as_ref().unwrap();
        let connection10 = &neuron1.connections[0];
        assert!(connection10.0 == 1usize);
        assert!(connection10.1 == 0.3f64);
        let connection11 = &neuron1.connections[1];
        assert!(connection11.0 == 0usize);
        assert!(connection11.1 == 0.4f64);
    }

    #[test]
    fn should_propagate_signal(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, 1f64);
        let sensors = vec![0f64];
        let mut output = vec![0f64];
        organism.activate(&sensors, &mut output);
        assert!(output[0] == 0.5f64, format!("{:?} is not 0.5", output[0]));
    }

}
<commit_msg>Adding testing for cyclic networks<commit_after>use neat::*;

#[derive(Debug, Clone)]
pub struct Organism {
    pub genome: Genome,
    pub fitness: f64,
    pub neurons: Vec<Option<Neuron>>
}

const ACTIVATION_CYCLES: usize = 5;

impl Organism {
    pub fn new(genome: Genome) -> Organism {
        Organism { genome: genome, fitness: 0f64, neurons: vec![] }
    }

    pub fn mutate(&mut self) {
        self.genome.mutate();
    }

    pub fn mate(&self, other: &Organism) -> Organism {
       Organism::new(self.genome.mate(&other.genome))
    }

    pub fn activate(&mut self, sensors: &Vec<f64>, outputs: &mut Vec<f64>){
       if self.neurons.len() == 0 {
           self.generate_phenome();
       };

       for neuron_id in 0..sensors.len() {
           if neuron_id < self.neurons.len() {
               self.neurons[neuron_id].as_mut().unwrap().stimulate(sensors[neuron_id]);
           }
       }

       for _n in 0..ACTIVATION_CYCLES {
           self.activate_neurons(sensors.len());
           self.propagate_signals();
       }

       //Take outputs from next neurons after sensors
       for neuron_id in sensors.len()..(sensors.len() + outputs.len()){
           if neuron_id < self.neurons.len() {
               outputs[neuron_id - sensors.len()] = self.neurons[neuron_id].as_ref().map_or(0f64, |neuron| neuron.stimulation());
           } else {
               outputs[neuron_id - sensors.len()] = 0f64;
           }
       }
    }

    fn activate_neurons(&mut self, sensor_neurons_size: usize){
        //Don't reset sensor neurons during activation
        for neuron_id in 0..sensor_neurons_size {
            self.neurons[neuron_id].as_mut().unwrap().shot(true);
        }

        for neuron_id in sensor_neurons_size..self.neurons.len() {
            self.neurons[neuron_id].as_mut().unwrap().shot(false);
        }
    }

    fn propagate_signals(&mut self){
        for neuron_option in self.neurons.clone() {
            let neuron = neuron_option.unwrap();
            for connection in &neuron.connections {
               self.neurons[connection.0].as_mut().unwrap().stimulate(neuron.potential() * connection.1);
            }
        }
    }

    fn generate_phenome(&mut self){
        let neurons_to_generate = self.genome.len();

        self.neurons = vec![None; neurons_to_generate as usize];

        for gene in self.genome.get_genes() {
            if self.neurons[gene.in_neuron_id].is_none(){
                self.neurons[gene.in_neuron_id] = Some(Neuron::new())
            }

            if self.neurons[gene.out_neuron_id].is_none(){
                self.neurons[gene.out_neuron_id] = Some(Neuron::new())
            }

            let mut neuron = self.neurons[gene.in_neuron_id].as_mut().unwrap();
            neuron.connections.push(Connection(gene.out_neuron_id, gene.weight));
        }
    }
}

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

    #[test]
    fn should_be_able_to_generate_his_phenome(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 0, 0.1f64);
        organism.genome.inject_gene(0, 1, 0.2f64);
        organism.genome.inject_gene(1, 1, 0.3f64);
        organism.genome.inject_gene(1, 0, 0.4f64);
        organism.generate_phenome();
        assert!(organism.neurons.len() == 2);
        let neuron0 = &organism.neurons[0].as_ref().unwrap();
        let connection00 = &neuron0.connections[0];
        assert!(connection00.0 == 0usize);
        assert!(connection00.1 == 0.1f64);
        let connection01 = &neuron0.connections[1];
        assert!(connection01.0 == 1usize);
        assert!(connection01.1 == 0.2f64);
        let neuron1 = &organism.neurons[1].as_ref().unwrap();
        let connection10 = &neuron1.connections[0];
        assert!(connection10.0 == 1usize);
        assert!(connection10.1 == 0.3f64);
        let connection11 = &neuron1.connections[1];
        assert!(connection11.0 == 0usize);
        assert!(connection11.1 == 0.4f64);
    }

    #[test]
    fn should_propagate_signal(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, 1f64);
        let sensors = vec![0f64];
        let mut output = vec![0f64];
        organism.activate(&sensors, &mut output);
        assert!(output[0] == 0.5f64, format!("{:?} is not 0.5", output[0]));
    }

    fn sigmoid(x: f64) -> f64 {
       1f64 / ( 1f64 +  (-x).exp() )
    }

    #[test]
    fn should_propagate_signal_over_hidden_layers(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, 0f64); //disable connection
        organism.genome.inject_gene(0, 2, 1f64);
        organism.genome.inject_gene(2, 1, 1f64);
        let sensors = vec![0f64];
        let mut output = vec![0f64];
        organism.activate(&sensors, &mut output);
        assert!(output[0] == sigmoid(sigmoid(sensors[0])), format!("{:?} is not 0.5", output[0]));
    }

    #[test]
    fn should_work_with_cyclic_networks(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, 1f64);
        organism.genome.inject_gene(1, 2, 1f64);
        organism.genome.inject_gene(2, 1, 1f64);
        let sensors = vec![0f64];
        let mut output = vec![0f64];
        organism.activate(&sensors, &mut output);
        let mut n1 = 0f64;
        let mut n2 = 0f64;
        for _n in 0..5 {
            let temp = n1;
            n1 = sigmoid(0f64) + sigmoid(n2);
            n2 = sigmoid(temp);
        }
        assert!(output[0] == n1, format!("{:?} is not {:?}", output[0], n1));
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use std::mem;
use std::ptr;
use libc::{c_int, c_ulong};

use runtime::Class;
use {Id, Message};

#[allow(improper_ctypes)]
#[link(name = "Foundation", kind = "framework")]
extern {
    static _NSConcreteStackBlock: Class;
}

#[repr(C)]
pub struct Block<A, R> {
    isa: *const Class,
    flags: c_int,
    _reserved: c_int,
    invoke: unsafe extern fn(*mut Block<A, R>, ...) -> R,
}

#[repr(C)]
struct ConcreteBlock<C: Clone> {
    isa: *const Class,
    flags: c_int,
    _reserved: c_int,
    pub invoke: unsafe extern fn(&mut ConcreteBlock<C>, ...),
    descriptor: *const BlockDescriptor<C>,
    pub context: C,
}

impl<C: Clone> ConcreteBlock<C> {
    pub fn new(invoke: unsafe extern fn(&mut ConcreteBlock<C>, ...), context: C) -> ConcreteBlock<C> {
        ConcreteBlock {
            isa: &_NSConcreteStackBlock,
            // 1 << 25 = BLOCK_HAS_COPY_DISPOSE
            flags: 1 << 25,
            _reserved: 0,
            invoke: invoke,
            // TODO: don't leak memory here
            descriptor: unsafe {
                mem::transmute(box BlockDescriptor::<C>::new())
            },
            context: context,
        }
    }

    pub fn copy(&self) -> Id<ConcreteBlock<C>> {
        unsafe {
            let block = msg_send![self copy] as *mut ConcreteBlock<C>;
            Id::from_retained_ptr(block)
        }
    }
}

impl<C: Clone> Message for ConcreteBlock<C> { }

impl<C: Clone> Clone for ConcreteBlock<C> {
    fn clone(&self) -> ConcreteBlock<C> {
        ConcreteBlock::new(self.invoke, self.context.clone())
    }
}

unsafe extern fn block_context_dispose<C: Clone>(block: &mut ConcreteBlock<C>) {
    let mut context = mem::uninitialized();
    ptr::copy_nonoverlapping_memory(&mut context, &block.context, 1);
    drop(context);
}

unsafe extern fn block_context_copy<C: Clone>(dst: &mut ConcreteBlock<C>, src: &ConcreteBlock<C>) {
    dst.context = src.context.clone();
}

#[repr(C)]
struct BlockDescriptor<C: Clone> {
    _reserved: c_ulong,
    block_size: c_ulong,
    copy_helper: unsafe extern fn(&mut ConcreteBlock<C>, &ConcreteBlock<C>),
    dispose_helper: unsafe extern fn(&mut ConcreteBlock<C>),
}

impl<C: Clone> BlockDescriptor<C> {
    pub fn new() -> BlockDescriptor<C> {
        BlockDescriptor {
            _reserved: 0,
            block_size: mem::size_of::<ConcreteBlock<C>>() as c_ulong,
            copy_helper: block_context_copy::<C>,
            dispose_helper: block_context_dispose::<C>,
        }
    }
}

#[cfg(test)]
mod tests {
    use std::mem;
    use objc_test_utils::invoke_int_block;
    use super::ConcreteBlock;

    #[test]
    fn test_create_block() {
        extern fn block_get_int(block: &ConcreteBlock<int>) -> int {
            block.context
        }

        let result = unsafe {
            let block = ConcreteBlock::new(mem::transmute(block_get_int), 13i);
            invoke_int_block(mem::transmute(&block))
        };
        assert!(result == 13);
    }
}
<commit_msg>Added BlockArguments trait.<commit_after>#![allow(dead_code)]

use std::mem;
use std::ptr;
use libc::{c_int, c_ulong};

use runtime::Class;
use {Id, Message};

#[allow(improper_ctypes)]
#[link(name = "Foundation", kind = "framework")]
extern {
    static _NSConcreteStackBlock: Class;
}

pub trait BlockArguments {
    fn invoke_block<R>(self, block: &Block<Self, R>) -> R;
}

#[repr(C)]
pub struct Block<A: BlockArguments, R> {
    isa: *const Class,
    flags: c_int,
    _reserved: c_int,
    invoke: unsafe extern fn(*mut Block<A, R>, ...) -> R,
}

impl<A: BlockArguments, R> Block<A, R> {
    pub fn call(&self, args: A) -> R {
        args.invoke_block(self)
    }
}

#[repr(C)]
struct ConcreteBlock<C: Clone> {
    isa: *const Class,
    flags: c_int,
    _reserved: c_int,
    pub invoke: unsafe extern fn(&mut ConcreteBlock<C>, ...),
    descriptor: *const BlockDescriptor<C>,
    pub context: C,
}

impl<C: Clone> ConcreteBlock<C> {
    pub fn new(invoke: unsafe extern fn(&mut ConcreteBlock<C>, ...), context: C) -> ConcreteBlock<C> {
        ConcreteBlock {
            isa: &_NSConcreteStackBlock,
            // 1 << 25 = BLOCK_HAS_COPY_DISPOSE
            flags: 1 << 25,
            _reserved: 0,
            invoke: invoke,
            // TODO: don't leak memory here
            descriptor: unsafe {
                mem::transmute(box BlockDescriptor::<C>::new())
            },
            context: context,
        }
    }

    pub fn copy(&self) -> Id<ConcreteBlock<C>> {
        unsafe {
            let block = msg_send![self copy] as *mut ConcreteBlock<C>;
            Id::from_retained_ptr(block)
        }
    }
}

impl<C: Clone> Message for ConcreteBlock<C> { }

impl<C: Clone> Clone for ConcreteBlock<C> {
    fn clone(&self) -> ConcreteBlock<C> {
        ConcreteBlock::new(self.invoke, self.context.clone())
    }
}

unsafe extern fn block_context_dispose<C: Clone>(block: &mut ConcreteBlock<C>) {
    let mut context = mem::uninitialized();
    ptr::copy_nonoverlapping_memory(&mut context, &block.context, 1);
    drop(context);
}

unsafe extern fn block_context_copy<C: Clone>(dst: &mut ConcreteBlock<C>, src: &ConcreteBlock<C>) {
    dst.context = src.context.clone();
}

#[repr(C)]
struct BlockDescriptor<C: Clone> {
    _reserved: c_ulong,
    block_size: c_ulong,
    copy_helper: unsafe extern fn(&mut ConcreteBlock<C>, &ConcreteBlock<C>),
    dispose_helper: unsafe extern fn(&mut ConcreteBlock<C>),
}

impl<C: Clone> BlockDescriptor<C> {
    pub fn new() -> BlockDescriptor<C> {
        BlockDescriptor {
            _reserved: 0,
            block_size: mem::size_of::<ConcreteBlock<C>>() as c_ulong,
            copy_helper: block_context_copy::<C>,
            dispose_helper: block_context_dispose::<C>,
        }
    }
}

#[cfg(test)]
mod tests {
    use std::mem;
    use objc_test_utils::invoke_int_block;
    use super::ConcreteBlock;

    #[test]
    fn test_create_block() {
        extern fn block_get_int(block: &ConcreteBlock<int>) -> int {
            block.context
        }

        let result = unsafe {
            let block = ConcreteBlock::new(mem::transmute(block_get_int), 13i);
            invoke_int_block(mem::transmute(&block))
        };
        assert!(result == 13);
    }
}
<|endoftext|>


<commit_before>use std::cell::{Cell, RefCell};
use std::rc::Rc;

#[derive(Debug, Clone, PartialEq)]
pub struct Token {
    category: String,
    lexeme: String,
}

fn lex(s: String) -> Vec<Token> {
    let mut tokens = vec![];

    for c in s.chars() {
        let (cat, lexeme) = match c {
            '|' => ("|", "".to_string()),
            '*' => ("*", "".to_string()),
            '+' => ("+", "".to_string()),
            '(' => ("(", "".to_string()),
            ')' => (")", "".to_string()),
            _ => ("Lit", c.to_string()),
        };

        tokens.push( Token{ category: cat.to_string(), lexeme: lexeme.to_string() } );
    }

    tokens.push( Token{ category: "EOF".to_string(), lexeme: "".to_string() } );

    tokens
}

#[derive(Debug)]
pub enum NodeCat {
    T(Token),
    NT(String),
}

#[derive(Debug)]
pub struct Node {
    category: NodeCat,
    children: Vec<Rc<RefCell<Node>>>,
}

impl Node {
    fn new_nt(val: &'static str) -> Rc<RefCell<Node>> {
        Rc::new(RefCell::new(Node {
            category: NodeCat::NT(val.to_string()),
            children: vec![],
        }))
    }

    fn new_t(val: Token) -> Rc<RefCell<Node>> {
        Rc::new(RefCell::new(Node {
            category: NodeCat::T(val),
            children: vec![],
        }))
    }

    fn print(&self) {
        println!("{:?}", self.category);
        for c in &self.children {
            println!("- {:?}", c.borrow().category);
        }

        for c in &self.children {
            if let NodeCat::NT(_) = c.borrow().category {
                c.borrow().print();
            }
        }
    }

    fn preorder_walk(x: Rc<RefCell<Node>>, level: usize) {
        let x = x.borrow();
        let separator = "|-- ";
        let s = format!("{}{:?}", separator, x.category);
        let space_n = level * separator.len();

        let mut space = String::new();
        for i in 0..space_n {
            space.push_str(" ");
        }
        println!("{}{}", space, s);

        for c in &x.children {
            Node::preorder_walk(c.clone(), level + 1);
        }
    }

    fn postorder_walk(x: Rc<RefCell<Node>>) {
        let x = x.borrow();
        for c in &x.children {
            //println!("{:?}", c);
            Node::postorder_walk(c.clone());
        }

        println!("{:?}", x.category);
    }
}

#[derive(Debug)]
pub struct Parser {
    index: Cell<usize>,
    src: String,
    tokens: Vec<Token>,
    tree: Rc<RefCell<Node>>,
    focus: RefCell<Rc<RefCell<Node>>>,
}

impl Parser {
    fn new(src: String) -> Parser {
        let tokens = lex(src.clone());
        let root = Node::new_nt("Re");
        Parser {
            index: Cell::new(0),
            src: src,
            tokens: tokens,
            tree: root.clone(),
            focus: RefCell::new(root.clone()),
        }
    }

    fn next(&self) {
        self.index.set(self.index.get() + 1);
    }

    fn print(&self) {
        println!("\nParser");
        let focus = self.focus.borrow();
        println!("focus {:?}", focus.borrow().category);
        Node::preorder_walk(self.tree.clone(), 0);
    }

    fn parse(&self) -> bool {
        return self.re();
    }

    fn re(&self) -> bool {
        let token = self.tokens.get(self.index.get()).expect("Re panic");

        println!("Re {:?}", token);

        match token.category.as_str() {
            // Re -> Lit Ops
            "Lit" => {
                {
                    let a = Node::new_t(token.clone());
                    let new_focus = Node::new_nt("Ops");

                    {
                        let focus = self.focus.borrow();
                        let mut focus = focus.borrow_mut();
                        focus.children.push(a);
                        focus.children.push(new_focus.clone());
                    }

                    *self.focus.borrow_mut() = new_focus;
                }
                self.next();
                return self.ops();
            },

            // Re -> ( Re ) Ops
            "(" => {
                let new_focus = Node::new_nt("Re");
                let ops_focus = Node::new_nt("Ops");
                {
                    {
                        let focus = self.focus.borrow();
                        let mut focus = focus.borrow_mut();
                        focus.children.push(Node::new_t(token.clone()));
                        focus.children.push(new_focus.clone());
                        focus.children.push(Node::new_t(Token { category: ")".to_string(), lexeme: "".to_string()}));
                        focus.children.push(ops_focus.clone());
                    }

                    *self.focus.borrow_mut() = new_focus;
                }

                self.next();
                if self.re() {
                    let token = self.tokens.get(self.index.get()).expect("Re panic");
                    if token.category == ")" {
                        {
                            *self.focus.borrow_mut() = ops_focus;
                        }
                        self.next();
                        return self.ops();
                    }
                }

                return false;
            },

            "EOF" => return true,

            _ => return false,
        }
    }

    fn ops(&self) -> bool {
        let token = self.tokens.get(self.index.get()).expect("Ops panic");

        println!("Ops {:?}", token);

        match token.category.as_str() {
            // Ops -> | Re
            // First
            "|" => {
                {
                    let a = Node::new_t(token.clone());
                    let new_focus = Node::new_nt("Re");

                    {
                        let focus = self.focus.borrow();
                        let mut focus = focus.borrow_mut();
                        focus.children.push(a);
                        focus.children.push(new_focus.clone());
                    }

                    *self.focus.borrow_mut() = new_focus;
                }
                self.next();
                return self.re();
            },
            // Ops -> * ReFinish
            // First
            "*" => {
                {
                    let a = Node::new_t(token.clone());
                    let new_focus = Node::new_nt("ReFinish");

                    {
                        let focus = self.focus.borrow();
                        let mut focus = focus.borrow_mut();
                        focus.children.push(a);
                        focus.children.push(new_focus.clone());
                    }

                    *self.focus.borrow_mut() = new_focus;
                }
                self.next();
                return self.re_finish();
            },
            // Ops -> + ReFinish
            // First
            "+" => {
                {
                    let a = Node::new_t(token.clone());
                    let new_focus = Node::new_nt("ReFinish");

                    {
                        let focus = self.focus.borrow();
                        let mut focus = focus.borrow_mut();
                        focus.children.push(a);
                        focus.children.push(new_focus.clone());
                    }

                    *self.focus.borrow_mut() = new_focus;
                }
                self.next();
                return self.re_finish();
            },

            // Follow
            "Lit" | "(" => {
                {
                    let new_focus = Node::new_nt("Re");

                    {
                        let focus = self.focus.borrow();
                        let mut focus = focus.borrow_mut();
                        focus.children.push(new_focus.clone());
                    }

                    *self.focus.borrow_mut() = new_focus;
                }
                return self.re();
            },

            // Follow
            ")" => {
                {
                    let focus = self.focus.borrow();
                    let mut focus = focus.borrow_mut();
                    focus.children.push(Node::new_t(Token { category: "Lambda".to_string(), lexeme: "".to_string()}));
                }
                return true;
            },

            // Follow
            "EOF" => {
                {
                    let focus = self.focus.borrow();
                    let mut focus = focus.borrow_mut();
                    focus.children.push(Node::new_t(Token { category: "EOF".to_string(), lexeme: "".to_string()}));
                }
                return true;
            },

            _ => return false,
        }
    }

    fn re_finish(&self) -> bool {
        let token = self.tokens.get(self.index.get()).expect("ReFinish panic");

        println!("ReFinish {:?}", token);

        match token.category.as_str() {
            // ReFinish -> Re
            // Follow
            "Lit" | "(" => {
                {
                    let new_focus = Node::new_nt("Re");

                    {
                        let focus = self.focus.borrow();
                        let mut focus = focus.borrow_mut();
                        focus.children.push(new_focus.clone());
                    }

                    *self.focus.borrow_mut() = new_focus;
                }
                return self.re();
            },
            // Follow
            ")" => {
                {
                    let focus = self.focus.borrow();
                    let mut focus = focus.borrow_mut();
                    focus.children.push(Node::new_t(Token { category: "Lambda".to_string(), lexeme: "".to_string()}));
                }
                return true;
            },
            // Follow
            "EOF" => {
                {
                    let focus = self.focus.borrow();
                    let mut focus = focus.borrow_mut();
                    focus.children.push(Node::new_t(Token { category: "EOF".to_string(), lexeme: "".to_string()}));
                }
                return true;
            },

            _ => return false,
        }
    }

}

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

    #[test]
    fn lex_test() {
        let cases = vec![
            ("a", vec![("Lit", "a"), ("EOF", "")]),
            ("aa", vec![("Lit", "a"), ("Lit", "a"), ("EOF", "")]),
            ("a|b|c", vec![("Lit", "a"), ("|", ""), ("Lit", "b"), ("|", ""), ("Lit", "c"), ("EOF", "")]),
            ("(a)", vec![("(", ""), ("Lit", "a"), (")", ""), ("EOF", "")]),
            ("a(b)", vec![("Lit", "a"), ("(", ""), ("Lit", "b"), (")", ""), ("EOF", "")]),
            //"(a|b)",
            //"(a|b)*",
        ];

        for (c, e) in cases {
            let expected: Vec<Token> = e.iter()
                .map(|&(cat, lexeme)| Token { category: cat.to_string(), lexeme: lexeme.to_string()})
                .collect();
            assert_eq!(lex(c.to_string()), expected);
        }
    }

    #[test]
    fn parse_test() {

        let cases = vec![
            "a",
            "(a)",
            "(aa)",
            "a*b",
            "(a*)b",
            "(a)*b",
            "a|(cde)*a+",
            "((((aaa))))",
        ];

        let expect = vec![
            true,
            true,
            true,
            true,
            true,
            true,
            true,
            true,
        ];

        for (c, e) in cases.iter().zip(expect.iter()) {
            println!("\nCase {:?}\n", c);
            let p = Parser::new(c.to_string());
            assert_eq!(p.parse(), *e, "In {:?}", c);
            p.print();
        }
    }

    #[test]
    fn engine_test() {

        let cases = vec![
            "a",
            //"(a)",
            //"(aa)",
            //"a*b",
            //"(a*)b",
            //"(a)*b",
            //"a|(cde)*a+",
            //"((((aaa))))",
        ];

        let expect = vec![
            true,
            true,
            true,
            true,
            true,
            true,
            true,
            true,
        ];

        for (c, e) in cases.iter().zip(expect.iter()) {
            println!("\nCase {:?}\n", c);
            let p = Parser::new(c.to_string());
            p.parse();
            println!("WALK");
            Node::postorder_walk(p.tree.clone());
            println!("TREE");
            p.print();
        }
    }
}
<commit_msg>wip: to_automata<commit_after>use std::cell::{Cell, RefCell};
use std::rc::Rc;

#[derive(Debug, Clone, PartialEq)]
pub struct Token {
    category: String,
    lexeme: String,
}

fn lex(s: String) -> Vec<Token> {
    let mut tokens = vec![];

    for c in s.chars() {
        let (cat, lexeme) = match c {
            '|' => ("|", "".to_string()),
            '*' => ("*", "".to_string()),
            '+' => ("+", "".to_string()),
            '(' => ("(", "".to_string()),
            ')' => (")", "".to_string()),
            _ => ("Lit", c.to_string()),
        };

        tokens.push( Token{ category: cat.to_string(), lexeme: lexeme.to_string() } );
    }

    tokens.push( Token{ category: "EOF".to_string(), lexeme: "".to_string() } );

    tokens
}

#[derive(Debug)]
pub enum NodeCat {
    T(Token),
    NT(String),
}

#[derive(Debug)]
pub struct Node {
    category: NodeCat,
    children: Vec<Rc<RefCell<Node>>>,
}

impl Node {
    fn new_nt(val: &'static str) -> Rc<RefCell<Node>> {
        Rc::new(RefCell::new(Node {
            category: NodeCat::NT(val.to_string()),
            children: vec![],
        }))
    }

    fn new_t(val: Token) -> Rc<RefCell<Node>> {
        Rc::new(RefCell::new(Node {
            category: NodeCat::T(val),
            children: vec![],
        }))
    }

    fn print(&self) {
        println!("{:?}", self.category);
        for c in &self.children {
            println!("- {:?}", c.borrow().category);
        }

        for c in &self.children {
            if let NodeCat::NT(_) = c.borrow().category {
                c.borrow().print();
            }
        }
    }

    fn preorder_walk(x: Rc<RefCell<Node>>, level: usize) {
        let x = x.borrow();
        let separator = "|-- ";
        let s = format!("{}{:?}", separator, x.category);
        let space_n = level * separator.len();

        let mut space = String::new();
        for i in 0..space_n {
            space.push_str(" ");
        }
        println!("{}{}", space, s);

        for c in &x.children {
            Node::preorder_walk(c.clone(), level + 1);
        }
    }

    fn postorder_walk(x: Rc<RefCell<Node>>) -> Option<String> {
        let x = x.borrow();

        if let NodeCat::T(ref token) = x.category {
            println!("{:?}", token);
            return Some(token.category.clone());
        }

        let to_concat: Vec<String> = x.children
            .iter()
            .map(|c| Node::postorder_walk(c.clone()))
            .filter(|x| x.is_some())
            .map(|x| x.unwrap())
            .collect();

        if to_concat.len() == 0 {
            return None;
        }

        Some(to_concat.join("") + "\n")
    }
}

#[derive(Debug)]
pub struct Parser {
    index: Cell<usize>,
    src: String,
    tokens: Vec<Token>,
    tree: Rc<RefCell<Node>>,
    focus: RefCell<Rc<RefCell<Node>>>,
}

impl Parser {
    fn new(src: String) -> Parser {
        let tokens = lex(src.clone());
        let root = Node::new_nt("Re");
        Parser {
            index: Cell::new(0),
            src: src,
            tokens: tokens,
            tree: root.clone(),
            focus: RefCell::new(root.clone()),
        }
    }

    fn next(&self) {
        self.index.set(self.index.get() + 1);
    }

    fn print(&self) {
        println!("\nParser");
        let focus = self.focus.borrow();
        println!("focus {:?}", focus.borrow().category);
        Node::preorder_walk(self.tree.clone(), 0);
    }

    fn parse(&self) -> bool {
        return self.re();
    }

    fn re(&self) -> bool {
        let token = self.tokens.get(self.index.get()).expect("Re panic");

        println!("Re {:?}", token);

        match token.category.as_str() {
            // Re -> Lit Ops
            "Lit" => {
                {
                    let a = Node::new_t(token.clone());
                    let new_focus = Node::new_nt("Ops");

                    {
                        let focus = self.focus.borrow();
                        let mut focus = focus.borrow_mut();
                        focus.children.push(a);
                        focus.children.push(new_focus.clone());
                    }

                    *self.focus.borrow_mut() = new_focus;
                }
                self.next();
                return self.ops();
            },

            // Re -> ( Re ) Ops
            "(" => {
                let new_focus = Node::new_nt("Re");
                let ops_focus = Node::new_nt("Ops");
                {
                    {
                        let focus = self.focus.borrow();
                        let mut focus = focus.borrow_mut();
                        focus.children.push(Node::new_t(token.clone()));
                        focus.children.push(new_focus.clone());
                        focus.children.push(Node::new_t(Token { category: ")".to_string(), lexeme: "".to_string()}));
                        focus.children.push(ops_focus.clone());
                    }

                    *self.focus.borrow_mut() = new_focus;
                }

                self.next();
                if self.re() {
                    let token = self.tokens.get(self.index.get()).expect("Re panic");
                    if token.category == ")" {
                        {
                            *self.focus.borrow_mut() = ops_focus;
                        }
                        self.next();
                        return self.ops();
                    }
                }

                return false;
            },

            "EOF" => return true,

            _ => return false,
        }
    }

    fn ops(&self) -> bool {
        let token = self.tokens.get(self.index.get()).expect("Ops panic");

        println!("Ops {:?}", token);

        match token.category.as_str() {
            // Ops -> | Re
            // First
            "|" => {
                {
                    let a = Node::new_t(token.clone());
                    let new_focus = Node::new_nt("Re");

                    {
                        let focus = self.focus.borrow();
                        let mut focus = focus.borrow_mut();
                        focus.children.push(a);
                        focus.children.push(new_focus.clone());
                    }

                    *self.focus.borrow_mut() = new_focus;
                }
                self.next();
                return self.re();
            },
            // Ops -> * ReFinish
            // First
            "*" => {
                {
                    let a = Node::new_t(token.clone());
                    let new_focus = Node::new_nt("ReFinish");

                    {
                        let focus = self.focus.borrow();
                        let mut focus = focus.borrow_mut();
                        focus.children.push(a);
                        focus.children.push(new_focus.clone());
                    }

                    *self.focus.borrow_mut() = new_focus;
                }
                self.next();
                return self.re_finish();
            },
            // Ops -> + ReFinish
            // First
            "+" => {
                {
                    let a = Node::new_t(token.clone());
                    let new_focus = Node::new_nt("ReFinish");

                    {
                        let focus = self.focus.borrow();
                        let mut focus = focus.borrow_mut();
                        focus.children.push(a);
                        focus.children.push(new_focus.clone());
                    }

                    *self.focus.borrow_mut() = new_focus;
                }
                self.next();
                return self.re_finish();
            },

            // Follow
            "Lit" | "(" => {
                {
                    let new_focus = Node::new_nt("Re");

                    {
                        let focus = self.focus.borrow();
                        let mut focus = focus.borrow_mut();
                        focus.children.push(new_focus.clone());
                    }

                    *self.focus.borrow_mut() = new_focus;
                }
                return self.re();
            },

            // Follow
            ")" => {
                {
                    let focus = self.focus.borrow();
                    let mut focus = focus.borrow_mut();
                    focus.children.push(Node::new_t(Token { category: "Lambda".to_string(), lexeme: "".to_string()}));
                }
                return true;
            },

            // Follow
            "EOF" => {
                {
                    let focus = self.focus.borrow();
                    let mut focus = focus.borrow_mut();
                    focus.children.push(Node::new_t(Token { category: "EOF".to_string(), lexeme: "".to_string()}));
                }
                return true;
            },

            _ => return false,
        }
    }

    fn re_finish(&self) -> bool {
        let token = self.tokens.get(self.index.get()).expect("ReFinish panic");

        println!("ReFinish {:?}", token);

        match token.category.as_str() {
            // ReFinish -> Re
            // Follow
            "Lit" | "(" => {
                {
                    let new_focus = Node::new_nt("Re");

                    {
                        let focus = self.focus.borrow();
                        let mut focus = focus.borrow_mut();
                        focus.children.push(new_focus.clone());
                    }

                    *self.focus.borrow_mut() = new_focus;
                }
                return self.re();
            },
            // Follow
            ")" => {
                {
                    let focus = self.focus.borrow();
                    let mut focus = focus.borrow_mut();
                    focus.children.push(Node::new_t(Token { category: "Lambda".to_string(), lexeme: "".to_string()}));
                }
                return true;
            },
            // Follow
            "EOF" => {
                {
                    let focus = self.focus.borrow();
                    let mut focus = focus.borrow_mut();
                    focus.children.push(Node::new_t(Token { category: "EOF".to_string(), lexeme: "".to_string()}));
                }
                return true;
            },

            _ => return false,
        }
    }

}

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

    #[test]
    fn lex_test() {
        let cases = vec![
            ("a", vec![("Lit", "a"), ("EOF", "")]),
            ("aa", vec![("Lit", "a"), ("Lit", "a"), ("EOF", "")]),
            ("a|b|c", vec![("Lit", "a"), ("|", ""), ("Lit", "b"), ("|", ""), ("Lit", "c"), ("EOF", "")]),
            ("(a)", vec![("(", ""), ("Lit", "a"), (")", ""), ("EOF", "")]),
            ("a(b)", vec![("Lit", "a"), ("(", ""), ("Lit", "b"), (")", ""), ("EOF", "")]),
            //"(a|b)",
            //"(a|b)*",
        ];

        for (c, e) in cases {
            let expected: Vec<Token> = e.iter()
                .map(|&(cat, lexeme)| Token { category: cat.to_string(), lexeme: lexeme.to_string()})
                .collect();
            assert_eq!(lex(c.to_string()), expected);
        }
    }

    #[test]
    fn parse_test() {

        let cases = vec![
            "a",
            "(a)",
            "(aa)",
            "a*b",
            "(a*)b",
            "(a)*b",
            "a|(cde)*a+",
            "((((aaa))))",
        ];

        let expect = vec![
            true,
            true,
            true,
            true,
            true,
            true,
            true,
            true,
        ];

        for (c, e) in cases.iter().zip(expect.iter()) {
            println!("\nCase {:?}\n", c);
            let p = Parser::new(c.to_string());
            assert_eq!(p.parse(), *e, "In {:?}", c);
            p.print();
        }
    }

    #[test]
    fn engine_test() {

        let cases = vec![
            "a",
            //"(a)",
            //"(aa)",
            //"a*b",
            //"(a*)b",
            //"(a)*b",
            //"a|(cde)*a+",
            //"((((aaa))))",
        ];

        let expect = vec![
            true,
            true,
            true,
            true,
            true,
            true,
            true,
            true,
        ];

        for (c, e) in cases.iter().zip(expect.iter()) {
            println!("\nCase {:?}\n", c);
            let p = Parser::new(c.to_string());
            p.parse();
            println!("WALK");
            println!("{:?}",Node::postorder_walk(p.tree.clone()));
            println!("TREE");
            p.print();
        }
    }
}
<|endoftext|>


<commit_before>use ascii::{AsAsciiStrError, AsciiChar, AsciiStr, AsciiString, ToAsciiChar, ToAsciiCharError};
use std::convert::{AsRef, AsMut, From, Into};
use std::{fmt, ptr, slice, str};
use ::PASCAL_STRING_BUF_SIZE;

/// An owned `PascalString`. This string type stores its data the stack. It is always 256 bytes long, with
/// the first byte storing the length.
///
/// This string uses the Ascii encoding.
#[repr(C)]
pub struct PascalString {
    /// The length of this string.
    len: u8,
    /// The characters of this string, encoded as an ascii array.
    chars: [AsciiChar; PASCAL_STRING_BUF_SIZE]
}

impl PascalString {
    /// Creates a new, empty `PascalString`.
    #[inline]
    pub fn new() -> Self {
        Default::default()
    }

    #[inline]
    pub fn from_bytes<B: AsRef<[u8]>>(bytes: B) -> Result<Self, PascalStringError> {
        PascalString::_from_bytes(bytes.as_ref())
    }

    fn _from_bytes(bytes: &[u8]) -> Result<Self, PascalStringError>  {
        let len = bytes.len();
        if len > PASCAL_STRING_BUF_SIZE {
            return Err(PascalStringError::OutOfBounds);
        }
        // Perform ascii check
        let ascii = try!(AsciiStr::from_ascii(bytes));

        let mut string = PascalString::new();
        string.len = len as u8;
        for i in 0..len {
            string.chars[i] = ascii[i];
        }
        Ok(string)
    }

    /// Push an ascii convertible character onto this string.
    ///
    /// # Panics
    ///
    /// Panics if the string is full, of if the `character` is not a valid ascii character.
    #[inline]
    pub fn push<C: ToAsciiChar>(&mut self, character: C) {
        self.try_push(character).unwrap();
    }

    /// Attempt to push an ascii convertible character onto the end of this `PascalString`.
    ///
    /// Returns `Err(_)` if the character cannot be pushed because this `PascalString` is full, or if
    /// `character` is not a valid ascii character.
    #[inline]
    pub fn try_push<C: ToAsciiChar>(&mut self, character: C) -> Result<(), PascalStringError> {
        self._try_push(try!(AsciiChar::from(character)))
    }

    fn _try_push(&mut self, ch: AsciiChar) -> Result<(), PascalStringError> {
        if self.is_full() {
            return Err(PascalStringError::OutOfBounds)
        }
        self.chars[self.len as usize] = ch;
        self.len += 1;
        Ok(())
    }

    /// Append a given string slice onto the end of this `PascalString`.
    ///
    /// # Panics
    ///
    /// Panics if the string cannot be pushed to because this `PascalString` is full.
    #[inline]
    pub fn push_str<S: AsRef<str>>(&mut self, s: S) {
        self.try_push_str(s).unwrap();
    }

    /// Attempt to append a given string slice onto the end of this `PascalString`.
    ///
    /// Returns `Err(_)` if the string cannot be pushed because this `PascalString` is full.
    #[inline]
    pub fn try_push_str<S: AsRef<str>>(&mut self, s: S) -> Result<(), PascalStringError> {
        self._try_push_str(s.as_ref())
    }

    fn _try_push_str(&mut self, s: &str) -> Result<(), PascalStringError> {
        unimplemented!()
    }

    /// Removes the last character from the string buffer and returns it.
    ///
    /// Returns `None` if this `PascalString` is empty.
    pub fn pop(&mut self) -> Option<AsciiChar> {
        if self.is_empty() {
            return None;
        }
        let c = self.chars[self.len as usize];
        self.len -= 1;
        Some(c)
    }

    pub fn remove(&mut self, index: u8) -> AsciiChar {
        assert!(self.len < index);
        let len = self.len as usize;
        let index = index as isize;
        let c = self.chars[len];
        // Shift everything to the right of the removed character to the left to cover up the hole
        // left.
        unsafe {
            let ptr = self.as_mut_ptr().offset(index);
            ptr::copy(ptr.offset(1), ptr, len - index.abs() as usize - 1);
        }
        self.len -= 1;
        c
    }

    #[inline]
    pub fn insert<C: ToAsciiChar>(&mut self, ch: C, index: u8) {
        self._insert(AsciiChar::from(ch).unwrap(), index)
    }

    fn _insert(&mut self, ch: AsciiChar, index: u8) {
        assert!(self.len < index);
        assert!(!self.is_full());
        let len = self.len as usize;
        let index = index as isize;
        // Shift everything to the right of `index` 1 place to the right to make room for the
        // new character.
        unsafe {
            let ptr = self.as_mut_ptr().offset(index);
            ptr::copy(ptr, ptr.offset(1), len - index.abs() as usize - 1);
        }
        self.chars[len] = ch;
        self.len += 1;
    }

    /// Truncates this String, removing all contents.
    ///
    /// Does not zero the values of the string.
    #[inline]
    pub fn clear(&mut self) {
        self.len = 0;
    }

    #[inline]
    pub fn len(&self) -> usize {
        self.len as usize
    }

    #[inline]
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    #[inline]
    pub fn is_full(&self) -> bool {
        self.len() == PASCAL_STRING_BUF_SIZE
    }

    /// Consumes this `PascalString`, and returns its inner state as a `[u8; 256]`, where the first byte
    /// is the length.
    ///
    /// Note that if the string has been truncated, bytes beyond the end of the string will not have been
    /// zeroed.
    #[inline]
    pub fn to_array(self) -> [u8; PASCAL_STRING_BUF_SIZE + 1] {
        self.into()
    }

    /// Get a pointer to the first byte of the string buffer.
    #[inline]
    pub fn as_ptr(&self) -> *const u8 {
        &self.chars as *const _ as *const u8
    }

    /// Get a mutable pointer to the first byte of the string buffer.
    #[inline]
    pub fn as_mut_ptr(&mut self) -> *mut u8 {
        &mut self.chars as *mut _ as *mut u8
    }
}

impl Default for PascalString {
    #[inline]
    fn default() -> Self {
        PascalString {
            len: 0,
            chars: [AsciiChar::Null; PASCAL_STRING_BUF_SIZE]
        }
    }
}

impl Clone for PascalString {
    fn clone(&self) -> Self {
        let mut clone = PascalString::default();
        clone.len = self.len;
        unsafe {
            ptr::copy_nonoverlapping(&self.chars, &mut clone.chars, PASCAL_STRING_BUF_SIZE);
        }
        clone
    }
}

impl fmt::Debug for PascalString {
    fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
        write!(fmtr, "{}", self)
    }
}

impl fmt::Display for PascalString {
    fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
        fmtr.pad(self.as_ref())
    }
}

impl AsRef<str> for PascalString {
    fn as_ref(&self) -> &str {
        let bytes: &[u8] = self.as_ref();
        str::from_utf8(bytes).unwrap()
    }
}

impl AsRef<[u8]> for PascalString {
    fn as_ref(&self) -> &[u8] {
        unsafe {
            slice::from_raw_parts(self.chars.as_ptr() as *const u8, self.len as usize)
        }
    }
}

impl AsRef<AsciiStr> for PascalString {
    fn as_ref(&self) -> &AsciiStr {
        let bytes: &[u8] = self.as_ref();
        AsciiStr::from_ascii(bytes).unwrap()
    }
}

impl AsRef<[AsciiChar]> for PascalString {
    fn as_ref(&self) -> &[AsciiChar] {
        unsafe {
            slice::from_raw_parts(self.chars.as_ptr(), self.len as usize)
        }
    }
}

impl AsMut<[AsciiChar]> for PascalString {
    fn as_mut(&mut self) -> &mut [AsciiChar] {
        unsafe {
            slice::from_raw_parts_mut(self.chars.as_mut_ptr(), self.len as usize)
        }
    }
}

impl Into<[u8; PASCAL_STRING_BUF_SIZE + 1]> for PascalString {
    fn into(self) -> [u8; PASCAL_STRING_BUF_SIZE + 1] {
        let mut array = [0u8; PASCAL_STRING_BUF_SIZE + 1];
        array[0] = self.len;
        unsafe {
            let chars_ptr = &self.chars as *const _ as *const [u8; PASCAL_STRING_BUF_SIZE];
            let array_ptr = (&mut array as *mut _).offset(1) as *mut [u8; PASCAL_STRING_BUF_SIZE];
            ptr::copy_nonoverlapping(chars_ptr, array_ptr, PASCAL_STRING_BUF_SIZE);
        }
        array
    }
}

impl Into<String> for PascalString {
    fn into(self) -> String {
        String::from_utf8_lossy(self.as_ref()).into_owned()
    }
}

#[derive(Debug, PartialEq)]
pub enum PascalStringError {
    OutOfBounds,
    InvalidChar(ToAsciiCharError),
    InvalidString(AsAsciiStrError)
}

impl From<ToAsciiCharError> for PascalStringError {
    fn from(e: ToAsciiCharError) -> Self {
        PascalStringError::InvalidChar(e)
    }
}

impl From<AsAsciiStrError> for PascalStringError {
    fn from(e: AsAsciiStrError) -> Self {
        PascalStringError::InvalidString(e)
    }
}<commit_msg>Various improvements.<commit_after>use ascii::{AsAsciiStrError, AsciiChar, AsciiStr, ToAsciiChar, ToAsciiCharError};
use std::convert::{AsRef, AsMut, From, Into};
use std::ops::{Deref, DerefMut};
use std::{fmt, mem, ptr, slice, str};
use ::{PascalStr, PASCAL_STRING_BUF_SIZE};

/// An owned `PascalString`. This string type stores its data the stack. It is always 256 bytes long, with
/// the first byte storing the length.
///
/// This string uses the Ascii encoding.
#[repr(C)]
pub struct PascalString {
    /// The length of this string.
    len: u8,
    /// The characters of this string, encoded as an ascii array.
    chars: [AsciiChar; PASCAL_STRING_BUF_SIZE]
}

impl PascalString {
    /// Creates a new, empty `PascalString`.
    #[inline]
    pub fn new() -> Self {
        Default::default()
    }

    #[inline]
    pub fn from_bytes<B: AsRef<[u8]>>(bytes: B) -> Result<Self, PascalStringError> {
        PascalString::_from_bytes(bytes.as_ref())
    }

    fn _from_bytes(bytes: &[u8]) -> Result<Self, PascalStringError>  {
        let len = bytes.len();
        if len > PASCAL_STRING_BUF_SIZE {
            return Err(PascalStringError::OutOfBounds);
        }
        // Perform ascii check
        let ascii = try!(AsciiStr::from_ascii(bytes));

        let mut string = PascalString::new();
        string.len = len as u8;
        for i in 0..len {
            string.chars[i] = ascii[i];
        }
        Ok(string)
    }

    /// Push an ascii convertible character onto this string.
    ///
    /// # Panics
    ///
    /// Panics if the string is full, of if the `character` is not a valid ascii character.
    #[inline]
    pub fn push<C: ToAsciiChar>(&mut self, character: C) {
        self.try_push(character).unwrap();
    }

    /// Attempt to push an ascii convertible character onto the end of this `PascalString`.
    ///
    /// Returns `Err(_)` if the character cannot be pushed because this `PascalString` is full, or if
    /// `character` is not a valid ascii character.
    #[inline]
    pub fn try_push<C: ToAsciiChar>(&mut self, character: C) -> Result<(), PascalStringError> {
        self._try_push(try!(AsciiChar::from(character)))
    }

    fn _try_push(&mut self, ch: AsciiChar) -> Result<(), PascalStringError> {
        if self.is_full() {
            return Err(PascalStringError::OutOfBounds)
        }
        self.chars[self.len as usize] = ch;
        self.len += 1;
        Ok(())
    }

    /// Append a given string slice onto the end of this `PascalString`.
    ///
    /// # Panics
    ///
    /// Panics if the string cannot be pushed to because this `PascalString` is full.
    #[inline]
    pub fn push_str<S: AsRef<str>>(&mut self, s: S) {
        self.try_push_str(s).unwrap();
    }

    /// Attempt to append a given string slice onto the end of this `PascalString`.
    ///
    /// Returns `Err(_)` if the string cannot be pushed because this `PascalString` is full.
    #[inline]
    pub fn try_push_str<S: AsRef<str>>(&mut self, s: S) -> Result<(), PascalStringError> {
        self._try_push_str(s.as_ref())
    }

    fn _try_push_str(&mut self, s: &str) -> Result<(), PascalStringError> {
        unimplemented!()
    }

    /// Removes the last character from the string buffer and returns it.
    ///
    /// Returns `None` if this `PascalString` is empty.
    pub fn pop(&mut self) -> Option<AsciiChar> {
        if self.is_empty() {
            return None;
        }
        let c = self.chars[self.len as usize];
        self.len -= 1;
        Some(c)
    }

    pub fn remove(&mut self, index: u8) -> AsciiChar {
        assert!(self.len < index);
        let len = self.len as usize;
        let index = index as isize;
        let c = self.chars[len];
        // Shift everything to the right of the removed character to the left to cover up the hole
        // left.
        unsafe {
            let ptr = self.as_mut_ptr().offset(index);
            ptr::copy(ptr.offset(1), ptr, len - index.abs() as usize - 1);
        }
        self.len -= 1;
        c
    }

    #[inline]
    pub fn insert<C: ToAsciiChar>(&mut self, ch: C, index: u8) {
        self._insert(AsciiChar::from(ch).unwrap(), index)
    }

    fn _insert(&mut self, ch: AsciiChar, index: u8) {
        assert!(self.len < index);
        assert!(!self.is_full());
        let len = self.len as usize;
        let index = index as isize;
        // Shift everything to the right of `index` 1 place to the right to make room for the
        // new character.
        unsafe {
            let ptr = self.as_mut_ptr().offset(index);
            ptr::copy(ptr, ptr.offset(1), len - index.abs() as usize - 1);
        }
        self.chars[len] = ch;
        self.len += 1;
    }

    /// Truncates this String, removing all contents.
    ///
    /// Does not zero the values of the string.
    #[inline]
    pub fn clear(&mut self) {
        self.len = 0;
    }

    /// Consumes this `PascalString`, and returns its inner state as a `[u8; 256]`, where the first byte
    /// is the length.
    ///
    /// Note that if the string has been truncated, bytes beyond the end of the string will not have been
    /// zeroed.
    #[inline]
    pub fn to_array(self) -> [u8; PASCAL_STRING_BUF_SIZE + 1] {
        self.into()
    }

    /// Get a pointer to the first byte of the string buffer.
    #[inline]
    pub fn as_ptr(&self) -> *const AsciiChar {
        self.chars.as_ptr()
    }

    /// Get a mutable pointer to the first byte of the string buffer.
    #[inline]
    pub fn as_mut_ptr(&mut self) -> *mut AsciiChar {
        self.chars.as_mut_ptr()
    }
}

impl Default for PascalString {
    #[inline]
    fn default() -> Self {
        PascalString {
            len: 0,
            chars: [AsciiChar::Null; PASCAL_STRING_BUF_SIZE]
        }
    }
}

impl Clone for PascalString {
    fn clone(&self) -> Self {
        let mut clone = PascalString::default();
        clone.len = self.len;
        unsafe {
            ptr::copy_nonoverlapping(&self.chars, &mut clone.chars, PASCAL_STRING_BUF_SIZE);
        }
        clone
    }
}

impl fmt::Debug for PascalString {
    fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
        write!(fmtr, "{}", self)
    }
}

impl fmt::Display for PascalString {
    fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
        fmtr.pad(self.as_ref())
    }
}

impl Deref for PascalString {
    type Target = PascalStr;
    fn deref(&self) -> &Self::Target {
        let ascii_str: &[AsciiChar] = self.as_ref();
        unsafe {
            mem::transmute(ascii_str)
        }
    }
}

impl DerefMut for PascalString {
    fn deref_mut(&mut self) -> &mut Self::Target {
        let ascii_str: &mut [AsciiChar] = self.as_mut();
        unsafe {
            mem::transmute(ascii_str)
        }
    }
}

impl AsRef<PascalStr> for PascalString {
    fn as_ref(&self) -> &PascalStr {
        self.deref()
    }
}

impl AsRef<str> for PascalString {
    fn as_ref(&self) -> &str {
        let bytes: &[u8] = self.as_ref();
        str::from_utf8(bytes).unwrap()
    }
}

impl AsRef<[u8]> for PascalString {
    fn as_ref(&self) -> &[u8] {
        unsafe {
            slice::from_raw_parts(self.chars.as_ptr() as *const u8, self.len as usize)
        }
    }
}

impl AsRef<AsciiStr> for PascalString {
    fn as_ref(&self) -> &AsciiStr {
        let bytes: &[u8] = self.as_ref();
        AsciiStr::from_ascii(bytes).unwrap()
    }
}

impl AsRef<[AsciiChar]> for PascalString {
    fn as_ref(&self) -> &[AsciiChar] {
        unsafe {
            slice::from_raw_parts(self.chars.as_ptr(), self.len as usize)
        }
    }
}

impl AsMut<[AsciiChar]> for PascalString {
    fn as_mut(&mut self) -> &mut [AsciiChar] {
        unsafe {
            slice::from_raw_parts_mut(self.chars.as_mut_ptr(), self.len as usize)
        }
    }
}

impl Into<[u8; PASCAL_STRING_BUF_SIZE + 1]> for PascalString {
    fn into(self) -> [u8; PASCAL_STRING_BUF_SIZE + 1] {
        let mut array = [0u8; PASCAL_STRING_BUF_SIZE + 1];
        array[0] = self.len;
        unsafe {
            let chars_ptr = &self.chars as *const _ as *const [u8; PASCAL_STRING_BUF_SIZE];
            let array_ptr = (&mut array as *mut _).offset(1) as *mut [u8; PASCAL_STRING_BUF_SIZE];
            ptr::copy_nonoverlapping(chars_ptr, array_ptr, PASCAL_STRING_BUF_SIZE);
        }
        array
    }
}

impl Into<String> for PascalString {
    fn into(self) -> String {
        String::from_utf8_lossy(self.as_ref()).into_owned()
    }
}

#[derive(Debug, PartialEq)]
pub enum PascalStringError {
    OutOfBounds,
    InvalidChar(ToAsciiCharError),
    InvalidString(AsAsciiStrError)
}

impl From<ToAsciiCharError> for PascalStringError {
    fn from(e: ToAsciiCharError) -> Self {
        PascalStringError::InvalidChar(e)
    }
}

impl From<AsAsciiStrError> for PascalStringError {
    fn from(e: AsAsciiStrError) -> Self {
        PascalStringError::InvalidString(e)
    }
}<|endoftext|>


<commit_before>use alga::linear::{FiniteDimInnerSpace, Rotation};
use na;
use math::{Isometry, Point};
use geometry::shape::Shape;
use geometry::query::{Contact, ContactPrediction};
use narrow_phase::{ContactDispatcher, ContactGenerator, IncrementalContactManifoldGenerator};

/// Contact manifold generator producing a full manifold at the first update.
///
/// Whenever a new contact is detected (i.e. when the current manifold is empty) a full manifold is
/// generated. Then, the manifold is incrementally updated by an
/// `IncrementalContactManifoldGenerator`.
#[derive(Clone)]
pub struct OneShotContactManifoldGenerator<P: Point, M, CD> {
    sub_detector: IncrementalContactManifoldGenerator<P, M, CD>,
}

impl<P, M, CD> OneShotContactManifoldGenerator<P, M, CD>
where
    P: Point,
    CD: ContactGenerator<P, M>,
{
    /// Creates a new one shot contact manifold generator.
    pub fn new(cd: CD) -> OneShotContactManifoldGenerator<P, M, CD> {
        OneShotContactManifoldGenerator {
            sub_detector: IncrementalContactManifoldGenerator::new(cd),
        }
    }
}

static ROT_ERROR: &'static str = "The provided transformation does not have enough \
                                  rotational degree of freedom for to work ith the \
                                  one-shot contact manifold generator.";
static TR_ERROR: &'static str = "The provided transformation does not have enough    \
                                 translational degree of freedom for to work ith the \
                                 one-shot contact manifold generator.";

impl<P, M, CD> ContactGenerator<P, M> for OneShotContactManifoldGenerator<P, M, CD>
where
    P: Point,
    M: Isometry<P>,
    CD: ContactGenerator<P, M>,
{
    fn update(
        &mut self,
        d: &ContactDispatcher<P, M>,
        m1: &M,
        g1: &Shape<P, M>,
        m2: &M,
        g2: &Shape<P, M>,
        prediction: &ContactPrediction<P::Real>,
    ) -> bool {
        if self.sub_detector.num_contacts() == 0 {
            // Do the one-shot manifold generation.
            match self.sub_detector
                .get_sub_collision(d, m1, g1, m2, g2, prediction)
            {
                Some(Some(coll)) => {
                    P::Vector::orthonormal_subspace_basis(&[*coll.normal], |b| {
                        let perturbation = M::Rotation::scaled_rotation_between(
                            &coll.normal,
                            &b,
                            na::convert(0.01),
                        ).expect(ROT_ERROR);
                        let shifted_m1 = m1.append_rotation_wrt_point(&perturbation, &coll.world1)
                            .expect(TR_ERROR);

                        let _ = self.sub_detector.add_new_contacts(
                            d,
                            &shifted_m1,
                            g1,
                            m2,
                            g2,
                            prediction,
                        );

                        // second perturbation (opposite direction)
                        let shifted_m1 =
                            m1.append_rotation_wrt_point(&na::inverse(&perturbation), &coll.world1)
                                .expect(TR_ERROR);
                        let _ = self.sub_detector.add_new_contacts(
                            d,
                            &shifted_m1,
                            g1,
                            m2,
                            g2,
                            prediction,
                        );

                        true
                    });

                    self.sub_detector.update_contacts(m1, m2, prediction.linear);

                    true
                }
                Some(None) => true, // no collision
                None => false,      // invalid
            }
        } else {
            // otherwise, let the incremental manifold do its job
            self.sub_detector.update(d, m1, g1, m2, g2, prediction)
        }
    }

    #[inline]
    fn num_contacts(&self) -> usize {
        self.sub_detector.num_contacts()
    }

    #[inline]
    fn contacts(&self, out_contacts: &mut Vec<Contact<P>>) {
        self.sub_detector.contacts(out_contacts)
    }
}
<commit_msg>One shot contact manifold generator: allow disabling dependency wrt. previous states.<commit_after>use alga::linear::{FiniteDimInnerSpace, Rotation};
use na;
use math::{Isometry, Point};
use geometry::shape::Shape;
use geometry::query::{Contact, ContactPrediction};
use narrow_phase::{ContactDispatcher, ContactGenerator, IncrementalContactManifoldGenerator};

/// Contact manifold generator producing a full manifold at the first update.
///
/// Whenever a new contact is detected (i.e. when the current manifold is empty) a full manifold is
/// generated. Then, the manifold is incrementally updated by an
/// `IncrementalContactManifoldGenerator`.
#[derive(Clone)]
pub struct OneShotContactManifoldGenerator<P: Point, M, CD> {
    sub_detector: IncrementalContactManifoldGenerator<P, M, CD>,
    always_one_shot: bool,
}

impl<P, M, CD> OneShotContactManifoldGenerator<P, M, CD>
where
    P: Point,
    CD: ContactGenerator<P, M>,
{
    /// Creates a new one shot contact manifold generator.
    pub fn new(cd: CD) -> OneShotContactManifoldGenerator<P, M, CD> {
        OneShotContactManifoldGenerator {
            sub_detector: IncrementalContactManifoldGenerator::new(cd),
            always_one_shot: false,
        }
    }

    // XXX: this should be an argument for the constructor.
    pub fn set_always_one_shot(&mut self, always_one_shot: bool) {
        self.always_one_shot = always_one_shot
    }
}

static ROT_ERROR: &'static str = "The provided transformation does not have enough \
                                  rotational degree of freedom for to work ith the \
                                  one-shot contact manifold generator.";
static TR_ERROR: &'static str = "The provided transformation does not have enough    \
                                 translational degree of freedom for to work ith the \
                                 one-shot contact manifold generator.";

impl<P, M, CD> ContactGenerator<P, M> for OneShotContactManifoldGenerator<P, M, CD>
where
    P: Point,
    M: Isometry<P>,
    CD: ContactGenerator<P, M>,
{
    fn update(
        &mut self,
        d: &ContactDispatcher<P, M>,
        m1: &M,
        g1: &Shape<P, M>,
        m2: &M,
        g2: &Shape<P, M>,
        prediction: &ContactPrediction<P::Real>,
    ) -> bool {
        if self.always_one_shot {
            self.sub_detector.clear();
        }

        if self.sub_detector.num_contacts() == 0 {
            // Do the one-shot manifold generation.
            match self.sub_detector
                .get_sub_collision(d, m1, g1, m2, g2, prediction)
            {
                Some(Some(coll)) => {
                    P::Vector::orthonormal_subspace_basis(&[*coll.normal], |b| {
                        let perturbation = M::Rotation::scaled_rotation_between(
                            &coll.normal,
                            &b,
                            na::convert(0.01),
                        ).expect(ROT_ERROR);
                        let shifted_m1 = m1.append_rotation_wrt_point(&perturbation, &coll.world1)
                            .expect(TR_ERROR);

                        let _ = self.sub_detector.add_new_contacts(
                            d,
                            &shifted_m1,
                            g1,
                            m2,
                            g2,
                            prediction,
                        );

                        // second perturbation (opposite direction)
                        let shifted_m1 =
                            m1.append_rotation_wrt_point(&na::inverse(&perturbation), &coll.world1)
                                .expect(TR_ERROR);
                        let _ = self.sub_detector.add_new_contacts(
                            d,
                            &shifted_m1,
                            g1,
                            m2,
                            g2,
                            prediction,
                        );

                        true
                    });

                    self.sub_detector.update_contacts(m1, m2, prediction.linear);

                    true
                }
                Some(None) => true, // no collision
                None => false,      // invalid
            }
        } else {
            // otherwise, let the incremental manifold do its job
            self.sub_detector.update(d, m1, g1, m2, g2, prediction)
        }
    }

    #[inline]
    fn num_contacts(&self) -> usize {
        self.sub_detector.num_contacts()
    }

    #[inline]
    fn contacts(&self, out_contacts: &mut Vec<Contact<P>>) {
        self.sub_detector.contacts(out_contacts)
    }
}
<|endoftext|>


<commit_before>use gameboy::irq::{Interrupt, Irq};

pub enum JoypadButton {
    Down,
    Start,
    Up,
    Select,
    Left,
    B,
    Right,
    A,
}

pub struct Joypad {
    pub data: u8,
    pub state: u8,
    pub cycles: usize,
}

impl Joypad {
    pub fn new() -> Joypad {
        Joypad {
            data: 0xFF,
            state: 0xFF,
            cycles: 0x00,
        }
    }

    pub fn step(&mut self, irq: &mut Irq, cycles: usize) -> Result<(), String> {
        self.cycles += cycles;

        if self.cycles >= 0x10000 {
            // 64hz
            self.cycles = 0x00;
            self.update(irq);
        }

        Ok(())
    }

    fn update(&mut self, irq: &mut Irq) {
        let mut d = self.data & 0xF0;

        if d & 0x30 == 0x10 {
            // Directional buttons
            d |= self.state & 0x0F;
        } else if d & 0x30 == 0x20 {
            // Non-directional buttons
            d |= self.state & 0x0F;
        } else if d & 0x30 == 0x30 {
            // Both ...
            d |= 0x0F;
        }

        if (self.data & !d & 0x0F) != 0x00 {
            irq.request(Interrupt::Joypad);
        }

        self.data = d;
    }

    pub fn from_u8(&mut self, b: u8, irq: &mut Irq) {
        self.data = (self.data & 0xCF) | (b & 0x30);
        self.update(irq);
    }

    pub fn press(&mut self, b: JoypadButton) {
        match b {
            JoypadButton::Down | JoypadButton::Start => self.state |= 0x08,
            JoypadButton::Up | JoypadButton::Select => self.state |= 0x04,
            JoypadButton::Left | JoypadButton::B => self.state |= 0x02,
            JoypadButton::Right | JoypadButton::A => self.state |= 0x01,
        }
    }

    pub fn unpress(&mut self, b: JoypadButton) {
        match b {
            JoypadButton::Down | JoypadButton::Start => self.state &= !0x08,
            JoypadButton::Up | JoypadButton::Select => self.state &= !0x04,
            JoypadButton::Left | JoypadButton::B => self.state &= !0x02,
            JoypadButton::Right | JoypadButton::A => self.state &= !0x01,
        }
    }
}
<commit_msg>Fix joypad issues<commit_after>use gameboy::irq::{Interrupt, Irq};

#[derive(Debug)]
pub enum JoypadButton {
    Down,
    Start,
    Up,
    Select,
    Left,
    B,
    Right,
    A,
}

pub struct Joypad {
    pub data: u8,
    pub state: u8,
    pub cycles: usize,
}

impl Joypad {
    pub fn new() -> Joypad {
        Joypad {
            data: 0xFF,
            state: 0xFF,
            cycles: 0x00,
        }
    }

    pub fn step(&mut self, irq: &mut Irq, cycles: usize) -> Result<(), String> {
        self.cycles += cycles;

        if self.cycles >= 0x10000 {
            // 64hz
            self.cycles = 0x00;
            self.update(irq);
            println!("Joypad: {:b}", self.data);
        }

        Ok(())
    }

    fn update(&mut self, irq: &mut Irq) {
        let mut d = self.data & 0xF0;

        if d & 0x30 == 0x10 {
            // Directional buttons
            let v = (self.state >> 0x04) & 0x0F;
            d |= v;
        } else if d & 0x30 == 0x20 {
            // Non-directional buttons
            let v = self.state & 0x0F;
            d |= v;
        } else if d & 0x30 == 0x30 {
            // Both ...
            d |= 0x0F;
        }

        if (self.data & !d & 0x0F) != 0x00 {
            irq.request(Interrupt::Joypad);
        }

        self.data = d;
    }

    pub fn from_u8(&mut self, b: u8, irq: &mut Irq) {
        self.data = (self.data & 0xCF) | (b & 0x30);
        self.update(irq);
    }

    pub fn unpress(&mut self, b: JoypadButton) {
        match b {
            JoypadButton::Down => self.state |= 0x08,
            JoypadButton::Start => self.state |= 0x80,
            JoypadButton::Up => self.state |= 0x04,
            JoypadButton::Select => self.state |= 0x40,
            JoypadButton::Left => self.state |= 0x02,
            JoypadButton::B => self.state |= 0x20,
            JoypadButton::Right => self.state |= 0x01,
            JoypadButton::A => self.state |= 0x10,
        }
    }

    pub fn press(&mut self, b: JoypadButton) {
        match b {
            JoypadButton::Down => self.state &= !0x08,
            JoypadButton::Start => self.state &= !0x80,
            JoypadButton::Up => self.state &= !0x04,
            JoypadButton::Select => self.state &= !0x40,
            JoypadButton::Left => self.state &= !0x02,
            JoypadButton::B => self.state &= !0x20,
            JoypadButton::Right => self.state &= !0x01,
            JoypadButton::A => self.state &= !0x10,
        }
    }
}
<|endoftext|>


<commit_before>#[derive(Debug, Clone, Copy)]
pub enum Key {
    Up, Down, Left, Right, A, B, Select, Start
}

fn get_index(key: Key) -> usize {
    match key {
        Key::Up => 0,
        Key::Down => 1,
        Key::Left => 2,
        Key::Right => 3,
        Key::A => 4,
        Key::B => 5,
        Key::Select => 6,
        Key::Start => 7,
    }
}

pub struct Joypad {
    keys: [bool; 8],
    select_button_keys: bool,
    select_direction_keys: bool,
}

impl Joypad {
    pub fn new() -> Joypad {
        Joypad {
            keys: [false; 8],
            select_button_keys: false,
            select_direction_keys: false,
        }
    }

    ///Keydown event
    pub fn keydown(&mut self, key: Key) {
        let index = get_index(key);
        self.keys[index] = true;
    }

    ///Keyup event
    pub fn keyup(&mut self, key: Key) {
        let index = get_index(key);
        self.keys[index] = false;
    }

    ///Used to select buttons/dpad
    ///only bits 4 and 5 are writeable
    ///bit 5: p15 = select button keys (0 = select)
    ///bit 4: p14 = select dpad (0 = select)
    //TODO: what happens when they're both selected?
    pub fn write_joyp(&mut self, value: u8) {
        self.select_button_keys = value & 32 == 0;
        self.select_direction_keys = value & 16 == 0;
    }

    pub fn read_joyp(&self) -> u8 {
        let mut high: u8 = 0;
        if self.select_button_keys {
            high |= 32;
        }
        if self.select_direction_keys {
            high |= 16;
        }

        let mut low = 0;
        if self.select_button_keys {
            if self.keys[get_index(Key::Start)] {
                low |= 8;
            }
            if self.keys[get_index(Key::Select)] {
                low |= 4;
            }
            if self.keys[get_index(Key::A)] {
                low |= 2;
            }
            if self.keys[get_index(Key::B)] {
                low |= 1;
            }
        }
        else if self.select_direction_keys {
            if self.keys[get_index(Key::Down)] {
                low |= 8;
            }
            if self.keys[get_index(Key::Up)] {
                low |= 4;
            }
            if self.keys[get_index(Key::Left)] {
                low |= 2;
            }
            if self.keys[get_index(Key::Right)] {
                low |= 1;
            }
        }

        //Convert to active low and return
        !((high & 0xF0) | (low & 0x0F))
    }
}
<commit_msg>Clear high 2 bits of 0xFF00 when reading from joypad.<commit_after>#[derive(Debug, Clone, Copy)]
pub enum Key {
    Up, Down, Left, Right, A, B, Select, Start
}

fn get_index(key: Key) -> usize {
    match key {
        Key::Up => 0,
        Key::Down => 1,
        Key::Left => 2,
        Key::Right => 3,
        Key::A => 4,
        Key::B => 5,
        Key::Select => 6,
        Key::Start => 7,
    }
}

pub struct Joypad {
    keys: [bool; 8],
    select_button_keys: bool,
    select_direction_keys: bool,
}

impl Joypad {
    pub fn new() -> Joypad {
        Joypad {
            keys: [false; 8],
            select_button_keys: false,
            select_direction_keys: false,
        }
    }

    ///Keydown event
    pub fn keydown(&mut self, key: Key) {
        let index = get_index(key);
        self.keys[index] = true;
    }

    ///Keyup event
    pub fn keyup(&mut self, key: Key) {
        let index = get_index(key);
        self.keys[index] = false;
    }

    ///Used to select buttons/dpad
    ///only bits 4 and 5 are writeable
    ///bit 5: p15 = select button keys (0 = select)
    ///bit 4: p14 = select dpad (0 = select)
    //TODO: what happens when they're both selected?
    pub fn write_joyp(&mut self, value: u8) {
        self.select_button_keys = value & 32 == 0;
        self.select_direction_keys = value & 16 == 0;
    }

    pub fn read_joyp(&self) -> u8 {
        let mut high: u8 = 0;
        if self.select_button_keys {
            high |= 32;
        }
        if self.select_direction_keys {
            high |= 16;
        }

        let mut low = 0;
        if self.select_button_keys {
            if self.keys[get_index(Key::Start)] {
                low |= 8;
            }
            if self.keys[get_index(Key::Select)] {
                low |= 4;
            }
            if self.keys[get_index(Key::A)] {
                low |= 2;
            }
            if self.keys[get_index(Key::B)] {
                low |= 1;
            }
        }
        else if self.select_direction_keys {
            if self.keys[get_index(Key::Down)] {
                low |= 8;
            }
            if self.keys[get_index(Key::Up)] {
                low |= 4;
            }
            if self.keys[get_index(Key::Left)] {
                low |= 2;
            }
            if self.keys[get_index(Key::Right)] {
                low |= 1;
            }
        }

        //Convert to active low and return
        (!((high & 0xF0) | (low & 0x0F))) & 0xCF
    }
}
<|endoftext|>


<commit_before>// Zinc, the bare metal stack for rust.
// Copyright 2014 Lionel Flandrin <lionel@svkt.org>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! SPI module
//! Enables SPI interface on any of the 4 SSI (Synchronous Serial Interface) modules in TM4C microcontrollers

use hal::tiva_c::sysctl;
use util::support::get_reg_ref;

#[path="../../util/ioreg.rs"]
#[macro_use] mod ioreg;
#[path="../../util/wait_for.rs"]
#[macro_use] mod wait_for;

/// Clock source for SSI module
/// TODO(jamwaffles) Implement the ability to choose a clock source
// pub enum ClockSource {
//   /// System configured clock source
//   System = 0x0,

//   /// The Precision Internal Oscillator @16MHz
//   PIOSC  = 0x5,
// }

/// There are 4 SSI instances an SPI interface can use
#[allow(missing_docs)]
#[derive(Clone, Copy)]
pub enum SpiId {
  Spi0,
  Spi1,
  Spi2,
  Spi3,
}

/// Structure describing a single SPI interface
#[derive(Clone, Copy)]
pub struct Spi {
  /// SSI registers
  regs: &'static reg::Ssi,
}

impl Spi {
  /// Create and setup a UART.
  pub fn new(id: SpiId) -> Spi {

    let (periph, regs) = match id {
      SpiId::Spi0 => (sysctl::periph::ssi::SSI_0, reg::SSI_0),
      SpiId::Spi1 => (sysctl::periph::ssi::SSI_1, reg::SSI_1),
      SpiId::Spi2 => (sysctl::periph::ssi::SSI_2, reg::SSI_2),
      SpiId::Spi3 => (sysctl::periph::ssi::SSI_3, reg::SSI_3),
    };

    let spi = Spi { regs: get_reg_ref(regs) };

    periph.ensure_enabled();

    spi.configure();

    spi
  }

  /// Configure the SSI into SPI mode. Currently hard coded at 3.2MHz for 16MHz PIOSC
  fn configure(&self) {
    let sysclk = sysctl::clock::sysclk_get();

    self.regs.ssicr1
      .set_sse(false)
      .set_ms(false)
      .set_lbm(false);

    // 3.2MHz fixed bitrate for 16MHz crystal and 80MHz PLL
    self.regs.ssicpsr
      .set_cpsdvsr(25);

    self.regs.ssicr0
      .set_scr(0)
      .set_sph(false)
      .set_spo(false)
      .set_frf(0)     // SPI mode
      .set_dss(0x7);  // 8 bit frames

    // Turn on SSI now that we've configured it
    self.regs.ssicr1
      .set_sse(true);
  }

  /// Wait for SSI TX FIFO to be ready
  /// This checks the busy flag (0 = not busy) and the "transmit FIFO not full" flag (1 = not full)
  fn writeable(&self) -> bool {
    !self.regs.ssisr.bsy() && self.regs.ssisr.tnf()
  }

  /// Wait for SSI data buffer to be readable
  fn readable(&self) -> bool {
    !self.regs.ssisr.bsy()
  }
}

impl ::hal::spi::Spi for Spi {
  fn write(&self, value: u8) {
    wait_for!(self.writeable());

    self.regs.ssidr.set_data(value as u16);
  }

  fn read(&self) -> u8 {
    wait_for!(self.readable());

    self.regs.ssidr.data() as u8
  }
}

#[allow(missing_docs)]
pub mod reg {
  //! SSI registers definition
  use volatile_cell::VolatileCell;
  use core::ops::Drop;

  ioregs!(Ssi = {
    /// SSI control register 0
    0x000 => reg16 ssicr0 {
      0..3 => dss: rw,    //= Data size select, 0x7 = 8 bits, see datasheet page 970 for other values
      4..5 => frf: rw,    //= Frame format, 0 = SPI 1 = TI SSF 2 Microwire
      6    => spo: rw,    //= SSI polarity, 0 = steady staate low on SSInCLK 1 = steady state high
      7    => sph: rw,    //= SSI clock phase, 1 = first edge 0 = second edge
      15..8 => scr: rw,   //= SSI clock rate, calculated from formula `SysClk / (CPSDVSR * (1 + SCR))`
    },

    /// SSI control register 1
    0x004 => reg16 ssicr1 {
      0 => lbm: rw,       //= Loopback enable, 1 = enabled 0 = normal operation
      1 => sse: rw,       //= Serial port enable 1 = enabled 0 = disabled. Must be cleared before SSI can be configured
      2 => ms: rw,        //= Master/slave select 0 = master 1 = slave
      4 => eot: rw,       //= End of transmission. Not sure what this is
    },

    /// SSI send/receive register
    /// When the SSIDR register is read, the entry in the receive FIFO that is pointed to by the current FIFO read pointer is accessed. When a data value is removed by the SSI receive logic from the incoming data frame, it is placed into the entry in the receive FIFO pointed to by the current FIFO write pointer.
    /// When the SSIDR register is written to, the entry in the transmit FIFO that is pointed to by the write pointer is written to. Data values are removed from the transmit FIFO one value at a time by the transmit logic. Each data value is loaded into the transmit serial shifter, then serially shifted out onto the SSInTx pin at the programmed bit rate.
    /// See page 973 in datasheet for more details
    0x008 => reg16 ssidr {
      0..15 => data: rw   //= Receive/transmit data
    },

    /// SSI status register
    0x00c => reg16 ssisr {
      0 => tfe: ro,       //= TX FIFO empty 1 = empty 0 = not empty
      1 => tnf: ro,       //= TX FIFO full 1 = not full 0 = full
      2 => rne: ro,       //= RX FIFO 1 = not empty 0 = empty
      3 => rff: ro,       //= RX FIFO full 0 = not full 1 = full
      4 => bsy: ro,       //= SSI busy 0 = idle, can send data 1 = transmitting, can't send data yet
    },

    /// SSI clock prescale register
    0x010 => reg16 ssicpsr {
      0..7 => cpsdvsr: rw //= SSI clock prescale divisor, 2 – 254 inclusive
    },

    /// SSI clock source configuration
    0xfc8 => reg16 ssicc {
      0..3 => cs: rw,     //= SSI baud clock source, 0x0 = system clock, 0x5 = PIOSC
    },
  });

  pub const SSI_0: *const Ssi = 0x40008000 as *const Ssi;
  pub const SSI_1: *const Ssi = 0x40009000 as *const Ssi;
  pub const SSI_2: *const Ssi = 0x4000A000 as *const Ssi;
  pub const SSI_3: *const Ssi = 0x4000B000 as *const Ssi;
}<commit_msg>Made Tiva C SPI frequency configurable<commit_after>// Zinc, the bare metal stack for rust.
// Copyright 2014 Lionel Flandrin <lionel@svkt.org>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! SPI module
//! Enables SPI interface on any of the 4 SSI (Synchronous Serial Interface) modules in TM4C microcontrollers

use hal::tiva_c::sysctl;
use util::support::get_reg_ref;

#[path="../../util/ioreg.rs"]
#[macro_use] mod ioreg;
#[path="../../util/wait_for.rs"]
#[macro_use] mod wait_for;

/// There are 4 SSI instances an SPI interface can use
#[allow(missing_docs)]
#[derive(Clone, Copy)]
pub enum SpiId {
  Spi0,
  Spi1,
  Spi2,
  Spi3,
}

/**
SPI configuration object

Configuration object used when instantiating an SPI instance

Note: The SPI GPIO pins must be set up correctly before using SPI. For example, for a master-only TX and CK config on SSI0,
the platformtree section might look like the following (taken from a Tiva C configuration):

```
gpio {
  a {
    spi_ck@2 {
      direction = "out";
      function  = 2;
    }

    spi_tx@5 {
      direction = "out";
      function  = 2;
    }
  }
}
```
*/
pub struct SpiConf {
  /// Which SPI peripheral to use. The Tiva C has 4 SSI interfaces that can be used for SPI
  pub peripheral: SpiId,

  /// Bus frequency in Hz. Peripheral clock scaling is calculated from this value to a possibly non-exact match
  pub frequency: u32,
}

/// Structure describing a single SPI interface
#[derive(Clone, Copy)]
pub struct Spi {
  /// SSI registers
  regs: &'static reg::Ssi,
}

impl Spi {
  /// Create and setup an SPI interface.
  pub fn new(config: SpiConf) -> Spi {

    let (periph, regs) = match config.peripheral {
      SpiId::Spi0 => (sysctl::periph::ssi::SSI_0, reg::SSI_0),
      SpiId::Spi1 => (sysctl::periph::ssi::SSI_1, reg::SSI_1),
      SpiId::Spi2 => (sysctl::periph::ssi::SSI_2, reg::SSI_2),
      SpiId::Spi3 => (sysctl::periph::ssi::SSI_3, reg::SSI_3),
    };

    let spi = Spi { regs: get_reg_ref(regs) };

    // Make sure peripheral clock gating is enabled
    periph.ensure_enabled();

    spi.configure(config);

    spi
  }

  /// Configure the SSI into SPI mode. Currently hard coded at 3.2MHz for 16MHz PIOSC
  fn configure(&self, config: SpiConf) {
    // Disable peripheral so we can configure it
    self.regs.ssicr1.set_sse(false);

    self.regs.ssicr1
      .set_sse(false)
      .set_ms(false)
      .set_lbm(false);

    // Set clock rate
    self.set_frequency(config.frequency);

    self.regs.ssicr0
      .set_sph(false)
      .set_spo(false)
      .set_frf(0)     // Put SSI into SPI mode
      .set_dss(0x7);  // 8 bit frames

    // Turn on peripheral now that we've configured it
    self.regs.ssicr1.set_sse(true);
  }

  /// Set SPI frequency
  ///
  /// This function computes the divisor and exponent (for lack of a better name). These are stored in `ssicpsr.cpsdvsr` and `ssicr0.scr` respectively.
  /// The clock rate formula (taken from the datasheet is) `ClockRate = SysClk / (CPSDVSR * (1 + SCR))` where SysClk is the system clock in Hz.
  fn set_frequency(&self, freq: u32) {
    let sysclk = sysctl::clock::sysclk_get() as u16;

    let mut divisor: u16 = 2;

    while divisor <= 254 {
      let prescale_hz: u16 = sysclk / divisor;

      // Calculate exponent
      let scr: u16 = ((prescale_hz as f32 / freq as f32) + 0.5f32) as u16;

      // Check we can support the divider
      if scr < 256 {
        self.regs.ssicpsr.set_cpsdvsr(divisor);

        self.regs.ssicr0.set_scr(scr - 1);

        return
      }

      divisor += 2;
    }

    // TODO(jamwaffles): Return a Result from here as well as the calling configure method
    unsafe { abort() };
  }

  /// Wait for SSI TX FIFO to be ready
  /// This checks the busy flag (0 = not busy) and the "transmit FIFO not full" flag (1 = not full)
  fn writeable(&self) -> bool {
    !self.regs.ssisr.bsy() && self.regs.ssisr.tnf()
  }

  /// Wait for SSI data buffer to be readable
  fn readable(&self) -> bool {
    !self.regs.ssisr.bsy()
  }
}

impl ::hal::spi::Spi for Spi {
  fn write(&self, value: u8) {
    wait_for!(self.writeable());

    self.regs.ssidr.set_data(value as u16);
  }

  fn read(&self) -> u8 {
    wait_for!(self.readable());

    self.regs.ssidr.data() as u8
  }
}

#[allow(missing_docs)]
pub mod reg {
  //! SSI registers definition
  use volatile_cell::VolatileCell;
  use core::ops::Drop;

  ioregs!(Ssi = {
    /// SSI control register 0
    0x000 => reg16 ssicr0 {
      0..3 => dss: rw,    //= Data size select, 0x7 = 8 bits, see datasheet page 970 for other values
      4..5 => frf: rw,    //= Frame format, 0 = SPI 1 = TI SSF 2 Microwire
      6    => spo: rw,    //= SSI polarity, 0 = steady staate low on SSInCLK 1 = steady state high
      7    => sph: rw,    //= SSI clock phase, 1 = first edge 0 = second edge
      15..8 => scr: rw,   //= SSI clock rate, calculated from formula `SysClk / (CPSDVSR * (1 + SCR))`
    },

    /// SSI control register 1
    0x004 => reg16 ssicr1 {
      0 => lbm: rw,       //= Loopback enable, 1 = enabled 0 = normal operation
      1 => sse: rw,       //= Serial port enable 1 = enabled 0 = disabled. Must be cleared before SSI can be configured
      2 => ms: rw,        //= Master/slave select 0 = master 1 = slave
      4 => eot: rw,       //= End of transmission. Not sure what this is
    },

    /// SSI send/receive register
    /// When the SSIDR register is read, the entry in the receive FIFO that is pointed to by the current FIFO read pointer is accessed. When a data value is removed by the SSI receive logic from the incoming data frame, it is placed into the entry in the receive FIFO pointed to by the current FIFO write pointer.
    /// When the SSIDR register is written to, the entry in the transmit FIFO that is pointed to by the write pointer is written to. Data values are removed from the transmit FIFO one value at a time by the transmit logic. Each data value is loaded into the transmit serial shifter, then serially shifted out onto the SSInTx pin at the programmed bit rate.
    /// See page 973 in datasheet for more details
    0x008 => reg16 ssidr {
      0..15 => data: rw   //= Receive/transmit data
    },

    /// SSI status register
    0x00c => reg16 ssisr {
      0 => tfe: ro,       //= TX FIFO empty 1 = empty 0 = not empty
      1 => tnf: ro,       //= TX FIFO full 1 = not full 0 = full
      2 => rne: ro,       //= RX FIFO 1 = not empty 0 = empty
      3 => rff: ro,       //= RX FIFO full 0 = not full 1 = full
      4 => bsy: ro,       //= SSI busy 0 = idle, can send data 1 = transmitting, can't send data yet
    },

    /// SSI clock prescale register
    0x010 => reg16 ssicpsr {
      0..7 => cpsdvsr: rw //= SSI clock prescale divisor, 2 – 254 inclusive
    },

    /// SSI clock source configuration
    0xfc8 => reg16 ssicc {
      0..3 => cs: rw,     //= SSI baud clock source, 0x0 = system clock, 0x5 = PIOSC
    },
  });

  pub const SSI_0: *const Ssi = 0x40008000 as *const Ssi;
  pub const SSI_1: *const Ssi = 0x40009000 as *const Ssi;
  pub const SSI_2: *const Ssi = 0x4000A000 as *const Ssi;
  pub const SSI_3: *const Ssi = 0x4000B000 as *const Ssi;
}<|endoftext|>