#[macro_export]
macro_rules! aluasm {
($( $tt:tt )+) => {{
use $crate::instr;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
let mut code: Vec<$crate::isa::Instr<$crate::LibId>> = Default::default();
#[allow(unreachable_code)] {
$crate::aluasm_inner! { code => $( $tt )+ }
}
code
}};
}
#[doc(hidden)]
#[macro_export]
macro_rules! aluasm_inner {
{ $code:ident => } => { };
{ $code:ident => offset $_:literal : $($tt:tt)* } => {
$crate::aluasm_inner! { $code => $( $tt )* }
};
{ $code:ident => site $lib:ident @ $_:literal : $($tt:tt)* } => {
$crate::aluasm_inner! { $code => $( $tt )* }
};
{ $code:ident => $masm:ident $label:ident : $($tt:tt)* } => {
$code.push(instr!{ $masm $label : });
$crate::aluasm_inner! { $code => $( $tt )* }
};
{ $code:ident => $op:ident ; $($tt:tt)* } => {
$code.push(instr!{ $op });
$crate::aluasm_inner! { $code => $( $tt )* }
};
{ $code:ident => $op:ident $( $arg:literal ),+ ; $($tt:tt)* } => {
$code.push(instr!{ $op $( $arg ),+ });
$crate::aluasm_inner! { $code => $( $tt )* }
};
{ $code:ident => $op:ident $( $arg:ident ),+ ; $($tt:tt)* } => {
$code.push(instr!{ $op $( $arg ),+ });
$crate::aluasm_inner! { $code => $( $tt )* }
};
{ $code:ident => $op:ident + $pos:literal ; $($tt:tt)* } => {
$code.push(instr!{ $op + $pos });
$crate::aluasm_inner! { $code => $( $tt )* }
};
{ $code:ident => $op:ident $arg:ident, + $pos:literal ; $($tt:tt)* } => {
$code.push(instr!{ $op $arg, + $pos });
$crate::aluasm_inner! { $code => $( $tt )* }
};
{ $code:ident => $op:ident - $pos:literal ; $($tt:tt)* } => {
$code.push(instr!{ $op - $pos });
$crate::aluasm_inner! { $code => $( $tt )* }
};
{ $code:ident => $op:ident $arg:ident, - $pos:literal ; $($tt:tt)* } => {
$code.push(instr!{ $op $arg, - $pos });
$crate::aluasm_inner! { $code => $( $tt )* }
};
{ $code:ident => $op:ident $arg:ident, $val:literal ; $($tt:tt)* } => {
$code.push(instr!{ $op $arg, $val });
$crate::aluasm_inner! { $code => $( $tt )* }
};
{ $code:ident => $op:ident $val:literal . $ty:ident ; $($tt:tt)* } => {
$code.push(instr!{ $op $val.$ty });
$crate::aluasm_inner! { $code => $( $tt )* }
};
{ $code:ident => $op:ident $reg:ident, $val:literal . $ty:ident ; $($tt:tt)* } => {
$code.push(instr!{ $op $reg, $val.$ty });
$crate::aluasm_inner! { $code => $( $tt )* }
};
{ $code:ident => $op:ident & $val:ident ; $($tt:tt)* } => {
$code.push(instr!{ $op & $val });
$crate::aluasm_inner! { $code => $( $tt )* }
};
{ $code:ident => $op:ident $reg:ident, & $val:ident ; $($tt:tt)* } => {
$code.push(instr!{ $op $reg, & $val });
$crate::aluasm_inner! { $code => $( $tt )* }
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! instr {
(routine $_:ident :) => {
$crate::isa::CtrlInstr::Nop.into()
};
(proc $_:ident :) => {
$crate::isa::CtrlInstr::Nop.into()
};
(label $_:ident :) => {
$crate::isa::CtrlInstr::Nop.into()
};
(loop $_:ident :) => {
$crate::isa::CtrlInstr::Nop.into()
};
(nop) => {
$crate::isa::CtrlInstr::Nop.into()
};
(chk CO) => {
$crate::isa::CtrlInstr::ChkCo.into()
};
(chk CK) => {
$crate::isa::CtrlInstr::ChkCk.into()
};
(not CO) => {
$crate::isa::CtrlInstr::NotCo.into()
};
(fail CK) => {
$crate::isa::CtrlInstr::FailCk.into()
};
(mov CO,CK) => {
$crate::isa::CtrlInstr::RsetCk.into()
};
(ret) => {
$crate::isa::CtrlInstr::Ret.into()
};
(stop) => {
$crate::isa::CtrlInstr::Stop.into()
};
(jmp $pos:literal) => {
$crate::isa::CtrlInstr::Jmp { pos: $pos }.into()
};
(jmp $pos:ident) => {
$crate::isa::CtrlInstr::Jmp { pos: $pos }.into()
};
(jif CO, + $shift:literal) => {
$crate::isa::CtrlInstr::ShOvfl { shift: $shift }.into()
};
(jif CO, - $shift:literal) => {
$crate::isa::CtrlInstr::ShOvfl { shift: -$shift }.into()
};
(jif CK, + $shift:literal) => {
$crate::isa::CtrlInstr::ShFail { shift: $shift }.into()
};
(jif CK, - $shift:literal) => {
$crate::isa::CtrlInstr::ShFail { shift: -$shift }.into()
};
(jif CO, $pos:literal) => {
$crate::isa::CtrlInstr::JiOvfl { pos: $pos }.into()
};
(jif CK, $pos:literal) => {
$crate::isa::CtrlInstr::JiFail { pos: $pos }.into()
};
(jif CO, $pos:ident) => {
$crate::isa::CtrlInstr::JiOvfl { pos: $pos }.into()
};
(jif CK, $pos:ident) => {
$crate::isa::CtrlInstr::JiFail { pos: $pos }.into()
};
(jmp + $shift:literal) => {
$crate::isa::CtrlInstr::Sh { shift: $shift }.into()
};
(jmp - $shift:literal) => {
$crate::isa::CtrlInstr::Sh { shift: -$shift }.into()
};
(jmp $lib:ident, $pos:literal) => {
$crate::isa::CtrlInstr::Exec { site: $crate::Site::new($lib, $pos).into() }.into()
};
(jmp $lib:ident, $pos:ident) => {
$crate::isa::CtrlInstr::Exec { site: $crate::Site::new($lib, $pos).into() }.into()
};
(call $lib:ident, $pos:literal) => {
$crate::isa::CtrlInstr::Call { site: $crate::Site::new($lib, $pos).into() }.into()
};
(call $lib:ident, $pos:ident) => {
$crate::isa::CtrlInstr::Call { site: $crate::Site::new($lib, $pos).into() }.into()
};
(call $pos:literal) => {
$crate::isa::CtrlInstr::Fn { pos: $pos }.into()
};
(call $pos:ident) => {
$crate::isa::CtrlInstr::Fn { pos: $pos }.into()
};
(halt) => {
$crate::isa::ReservedInstr::default().into()
};
}