fn bind(lhs: &BindExpr, rhs: Value, state: &Vec<Value>) -> Vec<Vec<Value>> {
    use self::types::BindExpr::*;
    use self::types::MatchExpr::*;
    match *lhs {
        // If we are unbound, we no-op
        Normal(Unbound) => vec![state.clone()],
        // To bind to a variable,
        Normal(Var(v)) => {
            // If the variable is defined, check equality
            if v < state.len() {
                if state[v] == rhs {
                    vec![state.clone()]
                } else {
                    vec![]
                }
            // If the variable is to be defined, define it
            } else if v == state.len() {
                let mut next = state.clone();
                next.push(rhs.clone());
                vec![next]
            // Otherwise it is a malformed binding
            } else {
                panic!("Variable out of range")
            }
        }
        Normal(Const(ref v)) => {
            if *v == rhs {
                vec![state.clone()]
            } else {
                vec![]
            }
        }
        Destructure(ref lhss) => {
            let rhss = match rhs.get().downcast_ref::<Vec<Value>>() {
                Some(ref rhss) => rhss.iter(),
                _ => panic!("Attempted to destructure non-list"),
            };
            let mut next = vec![state.clone()];
            for (lhs, rhs) in lhss.iter().zip(rhss) {
                let mut next_next = vec![];
                for state in next {
                    next_next.extend(bind(lhs, rhs.clone(), &state));
                }
                next = next_next;
            }
            next
        }
        Iterate(ref inner) => {
            let rhss = match rhs.get().downcast_ref::<Vec<Value>>() {
                Some(ref rhss) => rhss.iter(),
                _ => panic!("Attempted to destructure non-list"),
            };
            rhss.flat_map(|rhs| bind(inner, rhs.clone(), &state))
                .collect()
        }
    }
}
// In an assignment statement, once the rhs has been computed, binds the
// rhs value onto the expression on the left, using the state to check that
// already bound variables are bound to the same things
// It returns list of output states, each of which is a list of var bindings
In an assignment statement, once the rhs has been computed, binds the
rhs value onto the expression on the left, using the state to check that
already bound variables are bound to the same things
It returns list of output states, each of which is a list of var bindings
In an assignment statement once the rhs has been computed binds the rhs value onto the expression on the left using the state to check that already bound variables are bound to the same things It returns list of output states each of which is a list of var bindings
fn bind(lhs: &BindExpr, rhs: Value, state: &Vec<Value>) -> Vec<Vec<Value>> {
    use self::types::BindExpr::*;
    use self::types::MatchExpr::*;
    match *lhs {
        // If we are unbound, we no-op
        Normal(Unbound) => vec![state.clone()],
        // To bind to a variable,
        Normal(Var(v)) => {
            // If the variable is defined, check equality
            if v < state.len() {
                if state[v] == rhs {
                    vec![state.clone()]
                } else {
                    vec![]
                }
            // If the variable is to be defined, define it
            } else if v == state.len() {
                let mut next = state.clone();
                next.push(rhs.clone());
                vec![next]
            // Otherwise it is a malformed binding
            } else {
                panic!("Variable out of range")
            }
        }
        Normal(Const(ref v)) => {
            if *v == rhs {
                vec![state.clone()]
            } else {
                vec![]
            }
        }
        Destructure(ref lhss) => {
            let rhss = match rhs.get().downcast_ref::<Vec<Value>>() {
                Some(ref rhss) => rhss.iter(),
                _ => panic!("Attempted to destructure non-list"),
            };
            let mut next = vec![state.clone()];
            for (lhs, rhs) in lhss.iter().zip(rhss) {
                let mut next_next = vec![];
                for state in next {
                    next_next.extend(bind(lhs, rhs.clone(), &state));
                }
                next = next_next;
            }
            next
        }
        Iterate(ref inner) => {
            let rhss = match rhs.get().downcast_ref::<Vec<Value>>() {
                Some(ref rhss) => rhss.iter(),
                _ => panic!("Attempted to destructure non-list"),
            };
            rhss.flat_map(|rhs| bind(inner, rhs.clone(), &state))
                .collect()
        }
    }
}
fn bind ( lhs : & BindExpr , rhs : Value , state : & Vec < Value > ) -> Vec < Vec < Value > > { use self :: types :: BindExpr :: * ; use self :: types :: MatchExpr :: * ; match * lhs { // If we are unbound, we no-op Normal ( Unbound ) => vec ! [ state clone ( ) ] , // To bind to a variable, Normal ( Var ( v ) ) => { // If the variable is defined, check equality if v < state . len ( ) { if state [ v ] == rhs { vec ! [ state clone ( ) ] } else { vec ! [ ] } // If the variable is to be defined, define it } else if v == state . len ( ) { let mut next = state . clone ( ) ; next . push ( rhs . clone ( ) ) ; vec ! [ next ] // Otherwise it is a malformed binding } else { panic ! ( " " ) } } Normal ( Const ( ref v ) ) => { if * v == rhs { vec ! [ state clone ( ) ] } else { vec ! [ ] } } Destructure ( ref lhss ) => { let rhss = match rhs . get ( ) . downcast_ref :: < Vec < Value > > ( ) { Some ( ref rhss ) => rhss . iter ( ) , _ => panic ! ( " " ) , } ; let mut next = vec ! [ state clone ( ) ] ; for ( lhs , rhs ) in lhss . iter ( ) . zip ( rhss ) { let mut next_next = vec ! [ ] ; for state in next { next_next . extend ( bind ( lhs , rhs . clone ( ) , & state ) ) ; } next = next_next ; } next } Iterate ( ref inner ) => { let rhss = match rhs . get ( ) . downcast_ref :: < Vec < Value > > ( ) { Some ( ref rhss ) => rhss . iter ( ) , _ => panic ! ( " " ) , } ; rhss . flat_map ( | rhs | bind ( inner , rhs . clone ( ) , & state ) ) . collect ( ) } } }
In an assignment statement, once the rhs has been computed, binds the
rhs value onto the expression on the left, using the state to check that
already bound variables are bound to the same things
It returns list of output states, each of which is a list of var bindings
In an assignment statement once the rhs has been computed binds the rhs value onto the expression on the left using the state to check that already bound variables are bound to the same things It returns list of output states each of which is a list of var bindings
lhs
&BindExpr
rhs
Value
state
&Vec<Value>
lhs
&BindExpr
rhs
Value
state
&Vec<Value>