jsonpiler 0.11.0

a Json syntax programming language for Windows
Documentation
use crate::prelude::*;
built_in! {self, func, scope, string;
  {"Str", COMMON, Exact(1),
    int_to_str_x => {
      scope.e_x(load_int_x(Rcx, arg!(func, (Int(x)) => x).val)?)?;
      scope.p_x(Call(self.get_int_to_str_x(scope.id)?))?;
      scope.ret_str_x(Rax, HeapPtr)
    },
    int_to_str_a => {
      scope.e_a(load_int_a(X0, arg!(func, (Int(x)) => x).val)?)?;
      scope.p_a(Bl(self.get_int_to_str_a(scope.id)?))?;
      scope.ret_str_a(X1, X0, HeapPtr)
    }
  },
  {"len", COMMON, Exact(1),
    len_x => {
      scope.ee_x(vec![
        self.load_str_x(Rcx, &arg!(func, (Str(x)) => x).val)?,
        vec![Call(self.str_chars_len_x(scope.id)?)]
      ])?;
      Ok(Int(Var(scope.ret_x(S8, Rax)?)))
    },
    len_a => {
      scope.ee_a(vec![
        self.load_str_a(X0, &arg!(func, (Str(x)) => x).val)?,
        vec![Bl(self.str_chars_len_a(scope.id)?)]
      ])?;
      Ok(Int(Var(scope.ret_a(S8, X1, X0)?)))
    }
  },
  {"slice", COMMON, Range(2, 3),
  slice => {
    let str_chars_len = self.str_chars_len_x(scope.id)?;
    let utf8_slice = self.get_utf8_slice_x(scope.id)?;
    let string = arg!(func, (Str(x)) => x).val;
    let start_idx = arg!(func, (Int(x)) => x).val;
    if func.val.len == 3 {
      scope.e_x(load_int_x(R8, arg!(func, (Int(x)) => x).val)?)?;
    } else {
      scope.ee_x(vec![self.load_str_x(Rcx, &string)?, vec![Call(str_chars_len), mov(S8, R8, Rax)]])?;
    }
    scope.ee_x(vec![load_int_x(Rdx, start_idx)?, self.load_str_x(Rcx, &string)?, vec![Call(utf8_slice)]])?;
    scope.ret_str_x(Rax, HeapPtr)
  },
  slice_a => {
    let str_chars_len = self.str_chars_len_a(scope.id)?;
    let utf8_slice = self.get_utf8_slice_a(scope.id)?;
    let string = arg!(func, (Str(x)) => x).val;
    let start_idx = arg!(func, (Int(x)) => x).val;
    if func.val.len == 3 {
      scope.e_a(load_int_a(X2, arg!(func, (Int(x)) => x).val)?)?;
    } else {
      scope.ee_a(vec![self.load_str_a(X0, &string)?, vec![Bl(str_chars_len), MovRR(X2, X0)]])?;
    }
    scope.ee_a(vec![load_int_a(X1, start_idx)?, self.load_str_a(X0, &string)?, vec![Bl(utf8_slice)]])?;
    scope.ret_str_a(X1, X0, HeapPtr)
  }},
}
impl Jsonpiler {
  pub(crate) fn cat_str(
    &mut self,
    first: Bind<String>,
    func: &mut Pos<BuiltIn>,
    scope: &mut Scope,
  ) -> ErrOR<Json> {
    let mut strings = vec![first];
    for _ in 1..func.val.len {
      let arg = arg!(func, (Str(x)) => x);
      match &arg.val {
        Lit(string) => {
          if let Some(Lit(str)) = strings.last_mut() {
            str.push_str(string);
          } else {
            strings.push(arg.val.clone());
          }
        }
        Var(_) => strings.push(arg.val),
      }
    }
    if strings.len() == 1 && matches!(&strings[0], Lit(_)) {
      return Ok(Str(take(&mut strings[0])));
    }
    let buffer = scope.alloc_str(HeapPtr)?;
    let acc_len = scope.tmp(8, 8, func)?.v_rq();
    if self.flags.a64 {
      let mut string_vec = vec![];
      let str_len = self.str_len_a(scope.id)?;
      scope.ee_a(vec![vec![MovRR(X0, Xzr)], store_a(acc_len, X1, X0)?])?;
      for string in strings {
        let len = scope.tmp(8, 8, func)?.v_rq();
        string_vec.push(string.clone());
        scope.ee_a(vec![
          self.load_str_a(X0, &string)?,
          vec![Bl(str_len)],
          store_a(len, X1, X0)?,
          load_a(X1, acc_len)?,
          vec![AddR3(X0, X0, X1)],
          store_a(acc_len, X1, X0)?,
        ])?;
      }
      scope.ee_a(vec![
        load_a(X0, acc_len)?,
        vec![AddRI12(X0, X0, 1)],
        self.call_alloc_x0_a()?,
        store_a(buffer, X1, X0)?,
        vec![MovRR(X3, X0)],
      ])?;
      for st in string_vec {
        let start = self.id();
        let end = self.id();
        scope.ee_a(vec![
          self.load_str_a(X2, &st)?,
          vec![
            MovZ(X5, 0, Lsl0),
            LblA(start),
            LdR(S1, X4, X2, 0),
            CmpRR(X4, X5),
            BCc(E.into(), end),
            StR(S1, X4, X3, 0),
            AddRI12(X2, X2, 1),
            AddRI12(X3, X3, 1),
            B_(start),
            LblA(end),
          ],
        ])?;
      }
    } else {
      let mut string_vec = vec![];
      let str_len = self.str_len_x(scope.id)?;
      let tmp_s = scope.tmp(8, 8, func)?;
      let tmp_d = scope.tmp(8, 8, func)?;
      scope.e_x(vec![
        store(S8, tmp_s, Rsi),
        store(S8, tmp_d, Rdi),
        Clear(Rax),
        store(S8, acc_len.0, Rax),
      ])?;
      for string in strings {
        let len = scope.tmp(8, 8, func)?;
        string_vec.push((string.clone(), len.v_rq()));
        scope.ee_x(vec![
          self.load_str_x(Rcx, &string)?,
          vec![
            Call(str_len),
            store(S8, len, Rax),
            load(S8, Rcx, acc_len.0),
            RR(S8, Add, Rax, Rcx),
            store(S8, acc_len.0, Rax),
          ],
        ])?;
      }
      scope.ee_x(vec![
        vec![load(S8, R8, acc_len.0), IncR(R8)],
        self.call_alloc_r8_x()?,
        vec![store(S8, buffer.0, Rax), store(S8, Rdi, Rax)],
      ])?;
      for (st, len) in string_vec {
        scope.ee_x(vec![
          vec![load(S8, Rcx, len.0)],
          self.load_str_x(Rsi, &st)?,
          vec![DF(false), Repeat(S1, RepE, MovS)],
        ])?;
      }
      scope.e_x(vec![MovMIb(Ref(Rdi), 0), load(S8, Rsi, tmp_s), load(S8, Rdi, tmp_d)])?;
    }
    Ok(Str(Var(buffer)))
  }
}