jsonpiler 0.7.4

a Json syntax programming language for Windows
Documentation
use crate::{
  Arity::Exactly,
  Bind::{self, Lit, Var},
  CompilationErrKind::*,
  ErrOR, FuncInfo,
  Inst::*,
  InternalErrKind::*,
  Json, Jsonpiler,
  JsonpilerErr::*,
  Label,
  Memory::Global,
  Register::*,
  ScopeInfo, WithPos, built_in,
  dll::*,
  err, get_target_mem, take_arg, take_arg_custom,
  utility::{args_type_error, mov_b, mov_bool, mov_int, mov_q},
};
use core::mem::discriminant;
impl Jsonpiler {
  #[expect(clippy::cast_sign_loss, clippy::too_many_lines)]
  fn assign(&mut self, func: &mut FuncInfo, scope: &mut ScopeInfo, is_global: bool) -> ErrOR<Json> {
    let WithPos { value: variable, pos: var_pos } = take_arg!(self, func, (String(Lit(x))) => x);
    let json2 = func.arg()?;
    let ref_label = if is_global {
      if scope.get_var_local(&variable).is_some() {
        return err!(self, var_pos, ExistentVar(variable));
      }
      self.globals.get(&variable).cloned()
    } else {
      scope.get_var_local(&variable)
    };
    if let Some(json) = &ref_label
      && discriminant(json) != discriminant(&json2.value)
    {
      return Err(args_type_error(1, &format!("Variable `{variable}`"), json.type_name(), &json2));
    }
    let value = match json2.value {
      Json::String(string) => {
        if is_global {
          self.enter_c_s(scope)?;
        }
        let mem =
          get_target_mem!(self, scope, is_global, 8, ref_label, (String(Var(label))) => label);
        scope.push(match string {
          Lit(l_str) => {
            let id = self.global_str(l_str).0;
            LeaRM(Rax, Global { id })
          }
          Var(str_label) => mov_q(Rax, str_label.mem),
        });
        scope.push(mov_q(mem, Rax));
        if is_global {
          self.leave_c_s(scope)?;
        }
        Json::String(Var(Label { mem, size: 8 }))
      }
      Json::Null => Json::Null,
      Json::Int(Lit(int)) if is_global && ref_label.is_none() && scope.get_epilogue().is_none() => {
        Json::Int(Var(Label { mem: Global { id: self.global_num(int as u64) }, size: 8 }))
      }
      Json::Int(int) => {
        if is_global {
          self.enter_c_s(scope)?;
        }
        let mem = get_target_mem!(self, scope, is_global, 8, ref_label, (Int(Var(label))) => label);
        mov_int(&int, Rax, scope);
        scope.push(mov_q(mem, Rax));
        if is_global {
          self.leave_c_s(scope)?;
        }
        Json::Int(Var(Label { mem, size: 8 }))
      }
      Json::Bool(Lit(l_bool))
        if is_global && ref_label.is_none() && scope.get_epilogue().is_none() =>
      {
        Json::Bool(Var(Label { mem: Global { id: self.global_bool(l_bool) }, size: 1 }))
      }
      Json::Bool(boolean) => {
        if is_global {
          self.enter_c_s(scope)?;
        }
        let mem =
          get_target_mem!(self, scope, is_global, 1, ref_label, (Bool(Var(label))) => label);
        mov_bool(&boolean, Rax, scope);
        scope.push(mov_b(mem, Rax));
        if is_global {
          self.leave_c_s(scope)?;
        }
        Json::Bool(Var(Label { mem, size: 1 }))
      }
      Json::Float(Lit(l_float))
        if is_global && ref_label.is_none() && scope.get_epilogue().is_none() =>
      {
        Json::Float(Var(Label { mem: Global { id: self.global_num(l_float.to_bits()) }, size: 8 }))
      }
      Json::Float(float) => {
        if is_global {
          self.enter_c_s(scope)?;
        }
        let mem =
          get_target_mem!(self, scope, is_global, 8, ref_label, (Float(Var(label))) => label);
        scope.push(match float {
          Bind::Lit(l_float) => mov_q(Rax, l_float.to_bits()),
          Bind::Var(float_label) => mov_q(Rax, float_label.mem),
        });
        scope.push(mov_q(mem, Rax));
        if is_global {
          self.leave_c_s(scope)?;
        }
        Json::Float(Var(Label { mem, size: 8 }))
      }
      Json::Array(_) | Json::Object(_) => {
        return Err(args_type_error(
          2,
          &func.name,
          "Types excluding arrays and objects".into(),
          &json2,
        ));
      }
    };
    if is_global {
      self.globals.insert(variable, value);
    } else if ref_label.is_none() {
      scope.innermost_scope()?.insert(variable, value);
    }
    Ok(Json::Null)
  }
  fn enter_c_s(&mut self, scope: &mut ScopeInfo) -> ErrOR<()> {
    let critical_section = Global { id: self.get_critical_section()? };
    let enter_c_s = self.import(KERNEL32, "EnterCriticalSection")?;
    scope.extend(&[LeaRM(Rcx, critical_section), CallApi(enter_c_s)]);
    Ok(())
  }
  fn leave_c_s(&mut self, scope: &mut ScopeInfo) -> ErrOR<()> {
    let critical_section = Global { id: self.get_critical_section()? };
    let leave_c_s = self.import(KERNEL32, "LeaveCriticalSection")?;
    scope.extend(&[LeaRM(Rcx, critical_section), CallApi(leave_c_s)]);
    Ok(())
  }
}
built_in! {self, func, scope, variable;
  assign_global => {"global", COMMON, Exactly(2), {
    self.assign(func, scope, true)
  }},
  assign_local =>{ "=", COMMON, Exactly(2), {
    self.assign(func, scope, false)
  }},
  reference => {"$", COMMON, Exactly(1), {
    let var_name = take_arg!(self, func, (String(Lit(x))) => x);
    match self.get_var(&var_name.value, scope) {
      Some(var) => Ok(var),
      None => err!(self, var_name.pos, UndefinedVar(var_name.value)),
    }
  }},
  scope => {"scope", SP_SCOPE, Exactly(1), {
    let object = take_arg_custom!(self, func, "Block", (Object(Lit(x))) => x).value;
    self.eval_object(object, scope)
  }}
}