fn analyze_form_in_fn(
        &mut self,
        form: &Value,
        frames: &mut Vec<Frame>,
        captures: &mut Vec<CaptureSet>,
    ) -> EvaluationResult<Value> {
        match form {
            Value::Symbol(identifier, ns_opt) => {
                let current_frame_index = frames.len() - 1;
                for (frame_index, frame) in frames.iter().enumerate().rev() {
                    // NOTE: for now, need to side step rest of symbol resolution if a symbol
                    // is part of a forward declaration...
                    for scope in frame.forward_declarations.iter().rev() {
                        if let Some(Value::Symbol(resolved_identifier, None)) =
                            scope.get(identifier)
                        {
                            return Ok(Value::Symbol(resolved_identifier.clone(), None));
                        }
                    }
                    for scope in frame.scopes.iter().rev() {
                        match scope.get(identifier) {
                            Some(Value::Symbol(resolved_identifier, None)) => {
                                let reference_outlives_source = frame_index < current_frame_index;
                                // NOTE: current particularity of the implementation is to _not_
                                // capture forward declarations from `let*` bindings...
                                if reference_outlives_source {
                                    let captures_at_level = captures
                                        .last_mut()
                                        .expect("did push captures to grab earlier frame");
                                    // TODO: work through lifetimes here to avoid cloning...
                                    captures_at_level
                                        .insert((frame_index, resolved_identifier.clone()));
                                }
                                return Ok(Value::Symbol(resolved_identifier.clone(), None));
                            }
                            Some(other) => {
                                unreachable!("encountered unexpected value in `Scope`: {}", other)
                            }
                            None => {}
                        }
                    }
                }
                self.interpreter
                    .resolve_symbol_to_var(identifier, ns_opt.as_ref())
            }
            Value::List(elems) => {
                if elems.is_empty() {
                    return Ok(Value::List(PersistentList::new()));
                }

                let first = elems.first().unwrap();
                let rest = elems.drop_first().expect("list is not empty");
                if let Some(expansion) = self.interpreter.get_macro_expansion(first, &rest) {
                    match expansion? {
                        Value::List(elems) => self.analyze_list_in_fn(&elems, frames, captures),
                        other => self.analyze_form_in_fn(&other, frames, captures),
                    }
                } else {
                    self.analyze_list_in_fn(elems, frames, captures)
                }
            }
            Value::Vector(elems) => {
                let mut analyzed_elems = PersistentVector::new();
                for elem in elems.iter() {
                    let analyzed_elem = self.analyze_form_in_fn(elem, frames, captures)?;
                    analyzed_elems.push_back_mut(analyzed_elem);
                }
                Ok(Value::Vector(analyzed_elems))
            }
            Value::Map(elems) => {
                let mut analyzed_elems = PersistentMap::new();
                for (k, v) in elems.iter() {
                    let analyzed_k = self.analyze_form_in_fn(k, frames, captures)?;
                    let analyzed_v = self.analyze_form_in_fn(v, frames, captures)?;
                    analyzed_elems.insert_mut(analyzed_k, analyzed_v);
                }
                Ok(Value::Map(analyzed_elems))
            }
            Value::Set(elems) => {
                let mut analyzed_elems = PersistentSet::new();
                for elem in elems.iter() {
                    let analyzed_elem = self.analyze_form_in_fn(elem, frames, captures)?;
                    analyzed_elems.insert_mut(analyzed_elem);
                }
                Ok(Value::Set(analyzed_elems))
            }
            Value::Fn(_) => unreachable!(),
            Value::FnWithCaptures(_) => unreachable!(),
            Value::Primitive(_) => unreachable!(),
            Value::Recur(_) => unreachable!(),
            Value::Macro(_) => unreachable!(),
            Value::Exception(_) => unreachable!(),
            // Nil, Bool, Number, String, Keyword, Var, Atom
            other => Ok(other.clone()),
        }
    }
// Analyze symbols (recursively) in `form`:
// 1. Rewrite lambda parameters
// 2. Capture references to external vars
Analyze symbols (recursively) in `form`:
1. Rewrite lambda parameters
2. Capture references to external vars
Analyze symbols ( recursively ) in ` form ` : 1 . Rewrite lambda parameters 2 . Capture references to external vars
fn analyze_form_in_fn(
        &mut self,
        form: &Value,
        frames: &mut Vec<Frame>,
        captures: &mut Vec<CaptureSet>,
    ) -> EvaluationResult<Value> {
        match form {
            Value::Symbol(identifier, ns_opt) => {
                let current_frame_index = frames.len() - 1;
                for (frame_index, frame) in frames.iter().enumerate().rev() {
                    // NOTE: for now, need to side step rest of symbol resolution if a symbol
                    // is part of a forward declaration...
                    for scope in frame.forward_declarations.iter().rev() {
                        if let Some(Value::Symbol(resolved_identifier, None)) =
                            scope.get(identifier)
                        {
                            return Ok(Value::Symbol(resolved_identifier.clone(), None));
                        }
                    }
                    for scope in frame.scopes.iter().rev() {
                        match scope.get(identifier) {
                            Some(Value::Symbol(resolved_identifier, None)) => {
                                let reference_outlives_source = frame_index < current_frame_index;
                                // NOTE: current particularity of the implementation is to _not_
                                // capture forward declarations from `let*` bindings...
                                if reference_outlives_source {
                                    let captures_at_level = captures
                                        .last_mut()
                                        .expect("did push captures to grab earlier frame");
                                    // TODO: work through lifetimes here to avoid cloning...
                                    captures_at_level
                                        .insert((frame_index, resolved_identifier.clone()));
                                }
                                return Ok(Value::Symbol(resolved_identifier.clone(), None));
                            }
                            Some(other) => {
                                unreachable!("encountered unexpected value in `Scope`: {}", other)
                            }
                            None => {}
                        }
                    }
                }
                self.interpreter
                    .resolve_symbol_to_var(identifier, ns_opt.as_ref())
            }
            Value::List(elems) => {
                if elems.is_empty() {
                    return Ok(Value::List(PersistentList::new()));
                }
                let first = elems.first().unwrap();
                let rest = elems.drop_first().expect("list is not empty");
                if let Some(expansion) = self.interpreter.get_macro_expansion(first, &rest) {
                    match expansion? {
                        Value::List(elems) => self.analyze_list_in_fn(&elems, frames, captures),
                        other => self.analyze_form_in_fn(&other, frames, captures),
                    }
                } else {
                    self.analyze_list_in_fn(elems, frames, captures)
                }
            }
            Value::Vector(elems) => {
                let mut analyzed_elems = PersistentVector::new();
                for elem in elems.iter() {
                    let analyzed_elem = self.analyze_form_in_fn(elem, frames, captures)?;
                    analyzed_elems.push_back_mut(analyzed_elem);
                }
                Ok(Value::Vector(analyzed_elems))
            }
            Value::Map(elems) => {
                let mut analyzed_elems = PersistentMap::new();
                for (k, v) in elems.iter() {
                    let analyzed_k = self.analyze_form_in_fn(k, frames, captures)?;
                    let analyzed_v = self.analyze_form_in_fn(v, frames, captures)?;
                    analyzed_elems.insert_mut(analyzed_k, analyzed_v);
                }
                Ok(Value::Map(analyzed_elems))
            }
            Value::Set(elems) => {
                let mut analyzed_elems = PersistentSet::new();
                for elem in elems.iter() {
                    let analyzed_elem = self.analyze_form_in_fn(elem, frames, captures)?;
                    analyzed_elems.insert_mut(analyzed_elem);
                }
                Ok(Value::Set(analyzed_elems))
            }
            Value::Fn(_) => unreachable!(),
            Value::FnWithCaptures(_) => unreachable!(),
            Value::Primitive(_) => unreachable!(),
            Value::Recur(_) => unreachable!(),
            Value::Macro(_) => unreachable!(),
            Value::Exception(_) => unreachable!(),
            // Nil, Bool, Number, String, Keyword, Var, Atom
            other => Ok(other.clone()),
        }
    }
fn analyze_form_in_fn ( & mut self , form : & Value , frames : & mut Vec < Frame > , captures : & mut Vec < CaptureSet > , ) -> EvaluationResult < Value > { match form { Value :: Symbol ( identifier , ns_opt ) => { let current_frame_index = frames . len ( ) - 1 ; for ( frame_index , frame ) in frames . iter ( ) . enumerate ( ) . rev ( ) { // NOTE: for now, need to side step rest of symbol resolution if a symbol // is part of a forward declaration... for scope in frame . forward_declarations . iter ( ) . rev ( ) { if let Some ( Value :: Symbol ( resolved_identifier , None ) ) = scope . get ( identifier ) { return Ok ( Value :: Symbol ( resolved_identifier . clone ( ) , None ) ) ; } } for scope in frame . scopes . iter ( ) . rev ( ) { match scope . get ( identifier ) { Some ( Value :: Symbol ( resolved_identifier , None ) ) => { let reference_outlives_source = frame_index < current_frame_index ; // NOTE: current particularity of the implementation is to _not_ // capture forward declarations from `let*` bindings... if reference_outlives_source { let captures_at_level = captures . last_mut ( ) . expect ( " " ) ; // TODO: work through lifetimes here to avoid cloning... captures_at_level . insert ( ( frame_index , resolved_identifier . clone ( ) ) ) ; } return Ok ( Value :: Symbol ( resolved_identifier . clone ( ) , None ) ) ; } Some ( other ) => { unreachable ! ( " " other ) } None => { } } } } self . interpreter . resolve_symbol_to_var ( identifier , ns_opt . as_ref ( ) ) } Value :: List ( elems ) => { if elems . is_empty ( ) { return Ok ( Value :: List ( PersistentList :: new ( ) ) ) ; } let first = elems . first ( ) . unwrap ( ) ; let rest = elems . drop_first ( ) . expect ( " " ) ; if let Some ( expansion ) = self . interpreter . get_macro_expansion ( first , & rest ) { match expansion ? { Value :: List ( elems ) => self . analyze_list_in_fn ( & elems , frames , captures ) , other => self . analyze_form_in_fn ( & other , frames , captures ) , } } else { self . analyze_list_in_fn ( elems , frames , captures ) } } Value :: Vector ( elems ) => { let mut analyzed_elems = PersistentVector :: new ( ) ; for elem in elems . iter ( ) { let analyzed_elem = self . analyze_form_in_fn ( elem , frames , captures ) ? ; analyzed_elems . push_back_mut ( analyzed_elem ) ; } Ok ( Value :: Vector ( analyzed_elems ) ) } Value :: Map ( elems ) => { let mut analyzed_elems = PersistentMap :: new ( ) ; for ( k , v ) in elems . iter ( ) { let analyzed_k = self . analyze_form_in_fn ( k , frames , captures ) ? ; let analyzed_v = self . analyze_form_in_fn ( v , frames , captures ) ? ; analyzed_elems . insert_mut ( analyzed_k , analyzed_v ) ; } Ok ( Value :: Map ( analyzed_elems ) ) } Value :: Set ( elems ) => { let mut analyzed_elems = PersistentSet :: new ( ) ; for elem in elems . iter ( ) { let analyzed_elem = self . analyze_form_in_fn ( elem , frames , captures ) ? ; analyzed_elems . insert_mut ( analyzed_elem ) ; } Ok ( Value :: Set ( analyzed_elems ) ) } Value :: Fn ( _ ) => unreachable ! ( ) , Value :: FnWithCaptures ( _ ) => unreachable ! ( ) , Value :: Primitive ( _ ) => unreachable ! ( ) , Value :: Recur ( _ ) => unreachable ! ( ) , Value :: Macro ( _ ) => unreachable ! ( ) , Value :: Exception ( _ ) => unreachable ! ( ) , // Nil, Bool, Number, String, Keyword, Var, Atom other => Ok ( other . clone ( ) ) , } }
Analyze symbols (recursively) in `form`:
1.
Analyze symbols ( recursively ) in ` form ` : 1 .
&mut self
form
&Value
frames
&mut Vec<Frame>
captures
&mut Vec<CaptureSet>