Skip to content

Commit

Permalink
feat: add support for break debug command
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-ferdinand committed Oct 15, 2023
1 parent 07a54f6 commit 9bc7a5e
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
4 changes: 4 additions & 0 deletions triton-vm/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ pub enum LabelledInstruction {

/// Labels look like "`<name>:`" and are translated into absolute addresses.
Label(String),

Breakpoint,
}

impl LabelledInstruction {
Expand Down Expand Up @@ -77,6 +79,7 @@ impl Display for LabelledInstruction {
match self {
LabelledInstruction::Instruction(instr) => write!(f, "{instr}"),
LabelledInstruction::Label(label_name) => write!(f, "{label_name}:"),
LabelledInstruction::Breakpoint => write!(f, "break"),
}
}
}
Expand Down Expand Up @@ -469,6 +472,7 @@ pub(crate) fn build_label_to_address_map(program: &[LabelledInstruction]) -> Has
}
},
Instruction(instruction) => instruction_pointer += instruction.size() as u64,
Breakpoint => (),
}
}
label_map
Expand Down
24 changes: 23 additions & 1 deletion triton-vm/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ pub struct ParseError<'a> {
pub enum InstructionToken<'a> {
Instruction(AnInstruction<String>, &'a str),
Label(String, &'a str),
Breakpoint(&'a str),
}

impl<'a> Display for InstructionToken<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
InstructionToken::Instruction(instr, _) => write!(f, "{instr}"),
InstructionToken::Label(label_name, _) => write!(f, "{label_name}:"),
InstructionToken::Breakpoint(_) => write!(f, "break"),
}
}
}
Expand All @@ -60,6 +62,7 @@ impl<'a> InstructionToken<'a> {
match self {
InstructionToken::Instruction(_, token_str) => token_str,
InstructionToken::Label(_, token_str) => token_str,
InstructionToken::Breakpoint(token_str) => token_str,
}
}

Expand All @@ -68,6 +71,7 @@ impl<'a> InstructionToken<'a> {
match self {
Instruction(instr, _) => LabelledInstruction::Instruction(instr.to_owned()),
Label(label, _) => LabelledInstruction::Label(label.to_owned()),
Breakpoint(_) => LabelledInstruction::Breakpoint,
}
}
}
Expand Down Expand Up @@ -187,7 +191,7 @@ type ParseResult<'input, Out> = IResult<&'input str, Out, VerboseError<&'input s
///
pub fn tokenize(s: &str) -> ParseResult<Vec<InstructionToken>> {
let (s, _) = comment_or_whitespace0(s)?;
let (s, instructions) = many0(alt((label, labelled_instruction)))(s)?;
let (s, instructions) = many0(alt((label, labelled_instruction, breakpoint)))(s)?;
let (s, _) = context("expecting label, instruction or eof", eof)(s)?;

Ok((s, instructions))
Expand All @@ -213,6 +217,11 @@ fn label(label_s: &str) -> ParseResult<InstructionToken> {
Ok((s, InstructionToken::Label(addr, label_s)))
}

fn breakpoint(breakpoint_s: &str) -> ParseResult<InstructionToken> {
let (s, _) = token1("break")(breakpoint_s)?;
Ok((s, InstructionToken::Breakpoint(breakpoint_s)))
}

fn an_instruction(s: &str) -> ParseResult<AnInstruction<String>> {
// OpStack manipulation
let pop = instruction("pop", Pop);
Expand Down Expand Up @@ -1063,4 +1072,17 @@ pub(crate) mod tests {
let expected_instructions = vec![Instruction(Divine); DIGEST_LENGTH];
assert_eq!(expected_instructions, instructions);
}

#[test]
fn break_gets_turned_into_labelled_instruction() {
let instructions = triton_asm![break];
let expected_instructions = vec![Breakpoint];
assert_eq!(expected_instructions, instructions);
}

#[test]
fn break_does_not_propagate_to_full_program() {
let program = triton_program! { break halt break };
assert_eq!(1, program.instructions.len());
}
}

0 comments on commit 9bc7a5e

Please sign in to comment.