jsonpiler 0.7.4

a Json syntax programming language for Windows
Documentation
use crate::{
  Arity::Exactly,
  Bind::Lit,
  CompilationErrKind::*,
  ConditionCode::*,
  DataInst::RDAlign,
  ErrOR, FuncInfo,
  Inst::*,
  Json, Jsonpiler,
  JsonpilerErr::*,
  LogicByteOpcode::*,
  Memory::{Global, GlobalD},
  Operand::Args,
  Register::*,
  ScopeInfo, WithPos, built_in,
  dll::*,
  err, take_arg,
  utility::{args_type_error, mov_b, mov_d, mov_q},
};
use core::mem::discriminant;
built_in! {self, func, scope, gui;
init_gui => {"GUI", COMMON, Exactly(1), {
  const TITLE: &str = "J\0s\0o\0n\0p\0i\0l\0e\0r\0 \0G\0U\0I\0\0";
  let render_name = take_arg!(self, func, (String(Lit(x))) => x);
  let render_id;
  {
    let Some(render) = self.user_defined.get(&render_name.value) else {
      return err!(
        self, render_name.pos,
        UndefinedFn(render_name.value)
      );
    };
    let int = discriminant(&Json::Int(Lit(0)));
    if render.params.len() != 5
    {
      return err!(self, render_name.pos, ArityError { name: "render".into(), expected: Exactly(5), supplied: render.params.len() })
    }
    let mut nth = 0;
    for param in &render.params {
      nth += 1;
      if discriminant(param) != int
      {
        return Err(args_type_error(nth, "render", "Int".into(), &WithPos { value: param.clone(), pos: render_name.pos }));
      }
    }
    render_id = render.id;
  };
  scope.update_stack_args(8);
  let get_module_handle = self.import(KERNEL32, "GetModuleHandleW")?;
  let load_icon_w = self.import(USER32, "LoadIconW")?;
  let load_cursor_w = self.import(USER32, "LoadCursorW")?;
  let register_class_ex_w = self.import(USER32, "RegisterClassExW")?;
  let create_window_ex_w = self.import(USER32, "CreateWindowExW")?;
  let adjust_window_rect_ex = self.import(USER32, "AdjustWindowRectEx")?;
  let show_window = self.import(USER32, "ShowWindow")?;
  let update_window = self.import(USER32, "UpdateWindow")?;
  let get_message_w = self.import(USER32, "GetMessageW")?;
  let translate_message = self.import(USER32, "TranslateMessage")?;
  let dispatch_message_w = self.import(USER32, "DispatchMessageW")?;
  self.data_insts.push(RDAlign(2));
  let class_name = self.global_str(TITLE.into()).0;
  self.data_insts.push(RDAlign(2));
  let window_name = self.global_str(TITLE.into()).0;
  let wnd_proc = self.get_wnd_proc(render_id)?;
  let wnd_class = self.get_bss_id(0x50, 8);
  let msg = self.get_bss_id(0x30, 8);
  let gui_handle = self.get_bss_id(8, 8);
  let size_rect = self.get_bss_id(16, 8);
  let msg_loop = self.gen_id();
  let exit_gui = self.gen_id();
  scope.extend(&[
    mov_b(Rax, self.g_symbol("FLAG_GUI")),
    LogicRbRb(Test, Rax, Rax),
    JCc(Ne, self.get_custom_error("GUI already initialized")?),
    mov_b(self.g_symbol("FLAG_GUI"), 0xFF),
    mov_q(Rax, 0x40_0000_0050),
    mov_q(GlobalD { id: wnd_class, disp: 0x00 }, Rax),
    LeaRM(Rax, Global { id: wnd_proc }),
    mov_q(GlobalD { id: wnd_class, disp: 0x08 }, Rax),
    Clear(Rax),
    mov_q(GlobalD { id: wnd_class, disp: 0x10 }, Rax),
    Clear(Rcx),
  ]);
  scope.extend(&self.call_api_check_null(get_module_handle));
  scope.extend(&[
    mov_q(GlobalD { id: wnd_class, disp: 0x18 }, Rax),
    Clear(Rcx),
    mov_d(Rdx, 0x7F00),
  ]);
  scope.extend(&self.call_api_check_null(load_icon_w));
  scope.extend(&[
    mov_q(GlobalD { id: wnd_class, disp: 0x20 }, Rax),
    Clear(Rcx),
    mov_d(Rdx, 0x7F00),
  ]);
  scope.extend(&self.call_api_check_null(load_cursor_w));
  scope.extend(&[
    mov_q(GlobalD { id: wnd_class, disp: 0x28 }, Rax),
    mov_d(Rax, 6),
    mov_q(GlobalD { id: wnd_class, disp: 0x30 }, Rax),
    Clear(Rax),
    mov_q(GlobalD { id: wnd_class, disp: 0x38 }, Rax),
    LeaRM(Rax, Global { id: class_name }),
    mov_q(GlobalD { id: wnd_class, disp: 0x40 }, Rax),
    Clear(Rax),
    mov_q(GlobalD { id: wnd_class, disp: 0x48 }, Rax),
    LeaRM(Rcx, GlobalD { id: wnd_class, disp: 0 }),
  ]);
  scope.extend(&self.call_api_check_null(register_class_ex_w));
  scope.extend(&[
    mov_d(GlobalD { id: size_rect, disp: 8 }, Jsonpiler::GUI_W),
    mov_d(GlobalD { id: size_rect, disp: 12 }, Jsonpiler::GUI_H),
    LeaRM(Rcx, GlobalD { id: size_rect, disp: 0 }),
    mov_d(Rdx, 0xCF_0000),
    Clear(R8),
    Clear(R9),
  ]);
  scope.extend(&self.call_api_check_null(adjust_window_rect_ex));
  scope.extend(&[
    mov_d(Rax, GlobalD { id: size_rect, disp: 8 }),
    mov_d(Rcx, GlobalD { id: size_rect, disp: 0 }),
    SubRR(Rax, Rcx),
    mov_q(Args(0x30), Rax),
    mov_d(Rax, GlobalD { id: size_rect, disp: 12 }),
    mov_d(Rcx, GlobalD { id: size_rect, disp: 4 }),
    SubRR(Rax, Rcx),
    mov_q(Args(0x38), Rax),
    mov_d(Rcx, 0x0004_0000),
    LeaRM(Rdx, Global { id: class_name }),
    LeaRM(R8, Global { id: window_name }),
    mov_d(R9, 0xCF_0000),
    mov_d(Rax, 0x8000_0000),
    mov_q(Args(0x20), Rax),
    mov_q(Args(0x28), Rax),
    Clear(Rax),
    mov_q(Args(0x40), Rax),
    mov_q(Args(0x48), Rax),
    mov_q(Args(0x58), Rax),
    mov_q(Rax, GlobalD { id: wnd_class, disp: 0x18 }),
    mov_q(Args(0x50), Rax)
  ]);
  scope.extend(&self.call_api_check_null(create_window_ex_w));
  scope.extend(&[
    mov_q(Global { id: gui_handle }, Rax),
    mov_q(Rcx, Global { id: gui_handle }),
    mov_d(Rdx, 5),
    CallApi(show_window),
    mov_q(Rcx, Global { id: gui_handle }),
  ]);
  scope.extend(&self.call_api_check_null(update_window));
  scope.extend(&[
    Lbl(msg_loop),
    LeaRM(Rcx, Global { id: msg }),
    Clear(Rdx),
    Clear(R8),
    Clear(R9),
    CallApi(get_message_w),
    IncR(Rax),
    LogicRR(Test, Rax, Rax),
    JCc(E, self.sym_table["WIN_HANDLER"]),
    DecR(Rax),
    LogicRR(Test, Rax, Rax),
    JCc(E, exit_gui),
    LeaRM(Rcx, Global { id: msg }),
    CallApi(translate_message),
    LeaRM(Rcx, Global { id: msg }),
    CallApi(dispatch_message_w),
    Jmp(msg_loop),
    Lbl(exit_gui),
  ]);
  Ok(Json::Null)
}}
}