jsonpiler 0.10.2

a Json syntax programming language for Windows
Documentation
use crate::prelude::*;
impl Jsonpiler {
  pub(crate) fn drop_all(&mut self, result: Json, scope: &mut Scope) -> ErrOR<()> {
    self.drop_json(result, false, scope);
    self.drop_all_local(scope)?;
    self.drop_global(scope)
  }
  pub(crate) fn drop_all_local(&mut self, scope: &mut Scope) -> ErrOR<()> {
    for _ in 0..scope.locals.len() {
      self.drop_scope(scope)?;
    }
    self.drop_var_table(
      take(&mut scope.local_top),
      |jsonpiler, json, scope_2| jsonpiler.drop_json(json, true, scope_2),
      scope,
    )
  }
  fn drop_global(&mut self, scope: &mut Scope) -> ErrOR<()> {
    let globals = take(&mut self.globals);
    self.drop_var_table(
      globals,
      |jsonpiler, json, scope_2| {
        if let Some(memory) = json.memory() {
          jsonpiler.heap_free(memory, scope_2);
        }
      },
      scope,
    )
  }
  #[expect(clippy::needless_pass_by_value)]
  pub(crate) fn drop_json(&mut self, json: Json, force: bool, scope: &mut Scope) {
    if let Some(memory @ Memory(Local(lifetime, offset), mem_type)) = json.memory()
      && (force || lifetime == Tmp)
    {
      scope.free(offset, mem_type);
      self.heap_free(memory, scope);
    }
  }
  pub(crate) fn drop_scope(&mut self, scope: &mut Scope) -> ErrOR<()> {
    self.drop_var_table(
      scope.locals.pop().unwrap_or_default(),
      |jsonpiler, json, scope_2| jsonpiler.drop_json(json, true, scope_2),
      scope,
    )
  }
  fn drop_var_table<F>(
    &mut self,
    var_table: BTreeMap<String, Pos<Variable>>,
    mut free: F,
    scope: &mut Scope,
  ) -> ErrOR<()>
  where
    F: FnMut(&mut Jsonpiler, Json, &mut Scope),
  {
    for (name, variable) in var_table {
      if variable.val.refs.is_empty() && !name.starts_with('_') {
        self.warn(variable.pos, UnusedName(variable.val.kind, name.clone()))?;
      }
      self.push_symbol(SymbolInfo {
        definition: Some(variable.pos),
        name,
        kind: variable.val.kind,
        json_type: variable.val.val.as_type(),
        refs: variable.val.refs,
      });
      free(self, variable.val.val, scope);
    }
    Ok(())
  }
  pub(crate) fn heap_free(&mut self, Memory(addr, mem_type): Memory, scope: &mut Scope) {
    if mem_type.heap == HeapPtr {
      let heap_free = self.import(KERNEL32, "HeapFree");
      scope.extend(&[
        mov_q(Rcx, Global(self.symbols[HEAP])),
        Clear(Rdx),
        mov_q(R8, addr),
        CallApiCheck(heap_free),
        DecMd(Global(self.symbols[LEAK_CNT])),
      ]);
    }
  }
}