fn resolve_assign(&mut self, name: SharedSymbol, redeclare: bool) -> UniqueSymbol {
        // if we've seen the symbol before but don't know where it's
        // defined
        if let Some(unique_symbol) = self.unresolved_hoists.get(&name) {
            if self.local_symbol(name).is_none() {
                // dbg!(self.nonlocal_symbol(name));
                // dbg!(&name);
                // dbg!(&self.symbol_table);
                // dbg!(&self.scopes);
                // // dbg!(&self.try_resolve(name));
                // // panic!();
                // // this is a definition; we've resolved it!
                let unique_symbol = unique_symbol.item;
                self.uncapture_all(unique_symbol);
                self.unresolved_hoists.remove(&name);
                self.local_scope().locals.push(unique_symbol);
                return unique_symbol;
            }
        }

        // if we haven't seen the symbol before,
        // we search backwards through scopes and build a hoisting
        // chain
        if !redeclare {
            if let Some(unique_symbol) = self.try_resolve(name) {
                return unique_symbol;
            }
        }

        // if we didn't find it by searching backwards, we declare
        // it in the current scope
        let unique_symbol = self.symbol_table.push(name);
        self.local_scope().locals.push(unique_symbol);
        return unique_symbol;
    }
Returns the unique usize of a local symbol.
If a variable is referenced before assignment,
this function will define it in all lexical scopes
once this variable is discovered, we remove the
definitions in all scopes below this one.
passerine/src/compiler/hoist.rs