Skip to content

Commit

Permalink
optionally give the same instruction multiple times in triton_asm!()
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-ferdinand committed Jul 12, 2023
1 parent 15d9b68 commit 8a23bc3
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
37 changes: 35 additions & 2 deletions triton-vm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ pub mod vm;
/// [from_code]: crate::program::Program::from_code
#[macro_export]
macro_rules! triton_program {
($($source_code:tt)*) => {{
{$($source_code:tt)*} => {{
let labelled_instructions = $crate::triton_asm!($($source_code)*);
$crate::program::Program::new(&labelled_instructions)
}};
Expand All @@ -109,6 +109,8 @@ macro_rules! triton_program {
/// Similar to [`triton_program!`](crate::triton_program), it is possible to use string-like
/// interpolation to insert instructions, arguments, labels, or other expressions.
///
/// Similar to [`vec!], a single instruction can be repeated a specified number of times.
///
/// The labels for instruction `call`, if any, are also parsed. Instruction `call` can refer to
/// a label defined later in the program, _i.e.,_ labels are not checked for existence or
/// uniqueness by this parser.
Expand All @@ -126,6 +128,20 @@ macro_rules! triton_program {
/// assert_eq!(7, instructions.len());
/// ```
///
/// One instruction repeated several times:
///
/// ```
/// # use triton_vm::triton_asm;
/// # use triton_vm::instruction::LabelledInstruction;
/// # use triton_vm::instruction::AnInstruction::ReadIo;
/// let instructions = triton_asm![read_io; 3];
/// assert_eq!(3, instructions.len());
/// assert_eq!(LabelledInstruction::Instruction(ReadIo), instructions[0]);
/// assert_eq!(LabelledInstruction::Instruction(ReadIo), instructions[1]);
/// assert_eq!(LabelledInstruction::Instruction(ReadIo), instructions[2]);
/// ```
///
///
/// # Panics
///
/// **Panics** if the instructions cannot be parsed.
Expand Down Expand Up @@ -159,7 +175,14 @@ macro_rules! triton_asm {
(@fmt $fmt:expr, $($args:expr,)*; {$e:expr} $($tail:tt)*) => {
$crate::triton_asm!(@fmt concat!($fmt, "{}"), $($args,)* $e,; $($tail)*)
};
($($source_code:tt)*) => {{

[push $arg:literal; $num:literal] => { vec![ $crate::triton_instr!(push $arg); $num ] };
[dup $arg:literal; $num:literal] => { vec![ $crate::triton_instr!(dup $arg); $num ] };
[swap $arg:literal; $num:literal] => { vec![ $crate::triton_instr!(swap $arg); $num ] };
[call $arg:ident; $num:literal] => { vec![ $crate::triton_instr!(call $arg); $num ] };
[$instr:ident; $num:literal] => { vec![ $crate::triton_instr!($instr); $num ] };

{$($source_code:tt)*} => {{
let source_code = $crate::triton_asm!(@fmt "",; $($source_code)*);
let (_, instructions) = $crate::parser::tokenize(&source_code).unwrap();
$crate::parser::to_labelled_instructions(&instructions)
Expand All @@ -168,6 +191,16 @@ macro_rules! triton_asm {

/// Compile a single [Triton assembly][tasm] instruction into a [`LabelledInstruction`].
///
/// # Examples
///
/// ```
/// # use triton_vm::triton_instr;
/// # use triton_vm::instruction::LabelledInstruction;
/// # use triton_vm::instruction::AnInstruction::Call;
/// let instruction = triton_instr!(call my_label);
/// assert_eq!(LabelledInstruction::Instruction(Call("my_label".to_string())), instruction);
/// ```
///
/// [tasm]: https://triton-vm.org/spec/instructions.html
#[macro_export]
macro_rules! triton_instr {
Expand Down
11 changes: 11 additions & 0 deletions triton-vm/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1039,4 +1039,15 @@ pub mod parser_tests {
triton_instr!(call my_label)
);
}

#[test]
fn test_triton_asm_macro_repeating_one_instruction() {
let instructions = triton_asm![push 42; 3];
let expected_instructions = vec![Instruction(Push(42_u64.into())); 3];
assert_eq!(expected_instructions, instructions);

let instructions = triton_asm![read_io; 15];
let expected_instructions = vec![Instruction(ReadIo); 15];
assert_eq!(expected_instructions, instructions);
}
}

0 comments on commit 8a23bc3

Please sign in to comment.