fn analyze_fn_in_fn_with_possible_captures(
        &mut self,
        body: PersistentList<Value>,
        bindings: &PersistentVector<Value>,
        frames: &mut Vec<Frame>,
        captures: &mut Vec<CaptureSet>,
    ) -> EvaluationResult<Value> {
        captures.push(CaptureSet::new());
        let analyzed_fn = self.analyze_symbols_in_fn(body, bindings, frames, captures)?;
        let captures_at_this_level = captures.pop().expect("did push");
        if captures_at_this_level.is_empty() {
            return Ok(analyzed_fn);
        }
        let current_frame_index = frames.len() - 1;
        match analyzed_fn {
            Value::Fn(f) => {
                // Note: need to hoist captures if there are intervening functions along the way...
                for (captured_frame_index, capture) in &captures_at_this_level {
                    if *captured_frame_index < current_frame_index {
                        let target_captures = captures
                            .get_mut(*captured_frame_index)
                            .expect("already pushed captures");
                        target_captures.insert((*captured_frame_index, capture.to_string()));
                    }
                }
                let captures = captures_at_this_level
                    .iter()
                    .map(|(_, capture)| (capture.to_string(), None))
                    .collect();
                Ok(Value::FnWithCaptures(FnWithCapturesImpl { f, captures }))
            }
            _ => unreachable!("only returns Fn variant"),
        }
    }
// Note: can only have captures over enclosing fns if we have recursive nesting of fns
can only have captures over enclosing fns if we have recursive nesting of fns
can only have captures over enclosing fns if we have recursive nesting of fns
fn analyze_fn_in_fn_with_possible_captures(
        &mut self,
        body: PersistentList<Value>,
        bindings: &PersistentVector<Value>,
        frames: &mut Vec<Frame>,
        captures: &mut Vec<CaptureSet>,
    ) -> EvaluationResult<Value> {
        captures.push(CaptureSet::new());
        let analyzed_fn = self.analyze_symbols_in_fn(body, bindings, frames, captures)?;
        let captures_at_this_level = captures.pop().expect("did push");
        if captures_at_this_level.is_empty() {
            return Ok(analyzed_fn);
        }
        let current_frame_index = frames.len() - 1;
        match analyzed_fn {
            Value::Fn(f) => {
                // Note: need to hoist captures if there are intervening functions along the way...
                for (captured_frame_index, capture) in &captures_at_this_level {
                    if *captured_frame_index < current_frame_index {
                        let target_captures = captures
                            .get_mut(*captured_frame_index)
                            .expect("already pushed captures");
                        target_captures.insert((*captured_frame_index, capture.to_string()));
                    }
                }
                let captures = captures_at_this_level
                    .iter()
                    .map(|(_, capture)| (capture.to_string(), None))
                    .collect();
                Ok(Value::FnWithCaptures(FnWithCapturesImpl { f, captures }))
            }
            _ => unreachable!("only returns Fn variant"),
        }
    }
fn analyze_fn_in_fn_with_possible_captures ( & mut self , body : PersistentList < Value > , bindings : & PersistentVector < Value > , frames : & mut Vec < Frame > , captures : & mut Vec < CaptureSet > , ) -> EvaluationResult < Value > { captures . push ( CaptureSet :: new ( ) ) ; let analyzed_fn = self . analyze_symbols_in_fn ( body , bindings , frames , captures ) ? ; let captures_at_this_level = captures . pop ( ) . expect ( " " ) ; if captures_at_this_level . is_empty ( ) { return Ok ( analyzed_fn ) ; } let current_frame_index = frames . len ( ) - 1 ; match analyzed_fn { Value :: Fn ( f ) => { // Note: need to hoist captures if there are intervening functions along the way... for ( captured_frame_index , capture ) in & captures_at_this_level { if * captured_frame_index < current_frame_index { let target_captures = captures . get_mut ( * captured_frame_index ) . expect ( " " ) ; target_captures . insert ( ( * captured_frame_index , capture . to_string ( ) ) ) ; } } let captures = captures_at_this_level . iter ( ) . map ( | ( _ , capture ) | ( capture . to_string ( ) , None ) ) . collect ( ) ; Ok ( Value :: FnWithCaptures ( FnWithCapturesImpl { f , captures } ) ) } _ => unreachable ! ( " " ) , } }
Note: can only have captures over enclosing fns if we have recursive nesting of fns
Note : can only have captures over enclosing fns if we have recursive nesting of fns
&mut self
body
PersistentList<Value>
bindings
&PersistentVector<Value>
frames
&mut Vec<Frame>
captures
&mut Vec<CaptureSet>