jsonpiler 0.11.0

a Json syntax programming language for Windows
Documentation
use crate::prelude::*;
impl Jsonpiler {
  pub(crate) fn eval(&mut self, json: Pos<Json>, scope: &mut Scope) -> ErrOR<Pos<Json>> {
    Ok(if let Array(_, Lit(array)) = json.val {
      json.pos.with(Array(ArrayType::new(None, None), Lit(self.eval_args(array, scope)?)))
    } else if let Object(Lit(object)) = json.val {
      self.eval_object(json.pos.with(object), scope)?
    } else {
      json
    })
  }
  fn eval_args(&mut self, mut args: Vec<Pos<Json>>, scope: &mut Scope) -> ErrOR<Vec<Pos<Json>>> {
    for arg in &mut args {
      *arg = self.eval(take(arg), scope)?;
    }
    Ok(args)
  }
  fn eval_func(&mut self, (name, args): KeyVal, scope: &mut Scope) -> ErrOR<Json> {
    if let Some(builtin) = self.builtin.get_mut(&name.val) {
      builtin.refs.push(name.pos);
      let BuiltInInfo { scoped, skip_eval, builtin_x64, builtin_a64, arity, .. } = builtin.clone();
      let builtin_ptr = if self.flags.a64 {
        let Some(builtin_ptr) = builtin_a64 else {
          return Err(A64NotImplemented(name.val.clone()).into());
        };
        builtin_ptr
      } else {
        builtin_x64
      };
      if scoped {
        scope.locals.push(BTreeMap::new());
      }
      let mut func = self.func_info((name, args), skip_eval, scope)?;
      func.validate_args(arity)?;
      let result = builtin_ptr(self, &mut func, scope)?;
      if scoped {
        self.drop_scope(scope)?;
      }
      self.free_tmp_list(&mut func, scope)?;
      return Ok(result);
    }
    let Some(u_d) = self.user_defined.get(&name.val).cloned() else {
      return err!(name.pos, UndefinedFunc(name.val.clone()));
    };
    self.use_func(scope.id, u_d.val.dep.id);
    self.use_u_d(scope.id, u_d.val.dep.id, name.pos)?;
    let ret_type = name.pos.with(u_d.val.sig.ret_type);
    let mut func = self.func_info((name, args), false, scope)?;
    let stack_args_count = if self.flags.a64 {
      let float_stack = u_d
        .val
        .sig
        .params
        .iter()
        .filter(|(_, json_type)| *json_type == FloatT)
        .count()
        .saturating_sub(A64_ARG_REGS.len());
      let int_stack =
        u_d.val.sig.params.len().saturating_sub(float_stack).saturating_sub(A64_ARG_REGS.len());
      float_stack + int_stack
    } else {
      u_d.val.sig.params.len().saturating_sub(X64_ARG_REGS.len())
    } as u32;
    scope.update_stack_args_count(stack_args_count);
    func.validate_args(Exact(len_u32(&u_d.val.sig.params)?))?;
    let ret_json = if self.flags.a64 {
      let mut a_args = vec![];
      for (_, param_type) in u_d.val.sig.params {
        let arg = func.arg()?;
        if arg.val.as_type() != param_type {
          return Err(func.args_err(vec![param_type], &arg));
        }
        a_args.push(arg);
      }
      self.store_args_a(a_args, true, scope)?;
      scope.p_a(Bl(u_d.val.dep.id))?;
      scope.ret_json_take_a(&ret_type, X9, X0)?
    } else {
      let mut x_args = vec![];
      for (_, param_type) in u_d.val.sig.params {
        let arg = func.arg()?;
        if arg.val.as_type() != param_type {
          return Err(func.args_err(vec![param_type], &arg));
        }
        x_args.push(arg);
      }
      self.store_args_x(x_args, true, scope)?;
      scope.p_x(Call(u_d.val.dep.id))?;
      scope.ret_json_take_x(&ret_type, Rax)?
    };
    self.free_tmp_list(&mut func, scope)?;
    Ok(ret_json)
  }
  fn eval_object(&mut self, object: Pos<Vec<KeyVal>>, scope: &mut Scope) -> ErrOR<Pos<Json>> {
    let mut tmp_json = object.pos.with(Null(Lit(())));
    for key_val in object.val {
      self.drop_json(&tmp_json.val, false, scope)?;
      tmp_json.val = self.eval_func(key_val, scope)?;
    }
    Ok(tmp_json)
  }
  pub(crate) fn free_tmp_list(&mut self, func: &mut Pos<BuiltIn>, scope: &mut Scope) -> ErrOR<()> {
    for mem in &take(&mut func.val.tmp_list) {
      self.heap_free(*mem, scope)?;
      if let Memory(Local(Tmp, start), mem_type) = mem {
        scope.free(*start, mem_type.size()?)?;
      }
    }
    Ok(())
  }
  pub(crate) fn func_info(
    &mut self,
    (Pos { val: name, pos }, val): KeyVal,
    skip_eval: bool,
    scope: &mut Scope,
  ) -> ErrOR<Pos<BuiltIn>> {
    let args_vec = if let Array(_, Lit(args)) = val.val { args } else { vec![val] };
    let args = if skip_eval { args_vec } else { self.eval_args(args_vec, scope)? };
    let mut func = pos.with(BuiltIn {
      len: len_u32(&args)?,
      name,
      args: vec![].into_iter(),
      tmp_list: BTreeSet::new(),
      nth: 0,
    });
    if !skip_eval {
      for arg in &args {
        func.push_free_tmp(arg.val.mem());
      }
    }
    func.val.args = args.into_iter();
    Ok(func)
  }
}