Skip to content

Commit

Permalink
Allow comments inside blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
neysofu authored and garritfra committed Dec 28, 2024
1 parent 8789368 commit d73a3bb
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 16 deletions.
40 changes: 32 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,26 +389,50 @@ pub struct Block<'a> {
pub label: String,

/// A list of statements in the block
pub statements: Vec<Statement<'a>>,
pub items: Vec<BlockItem<'a>>,
}

/// See [`Block::items`];
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum BlockItem<'a> {
Statement(Statement<'a>),
Comment(String),
}

impl<'a> fmt::Display for BlockItem<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Statement(stmt) => write!(f, "{}", stmt),
Self::Comment(comment) => write!(f, "# {}", comment),
}
}
}

impl<'a> Block<'a> {
pub fn add_comment(&mut self, contents: impl Into<String>) {
self.items.push(BlockItem::Comment(contents.into()));
}

/// Adds a new instruction to the block
pub fn add_instr(&mut self, instr: Instr<'a>) {
self.statements.push(Statement::Volatile(instr));
self.items
.push(BlockItem::Statement(Statement::Volatile(instr)));
}

/// Adds a new instruction assigned to a temporary
pub fn assign_instr(&mut self, temp: Value, ty: Type<'a>, instr: Instr<'a>) {
self.statements
.push(Statement::Assign(temp, ty.into_base(), instr));
self.items.push(BlockItem::Statement(Statement::Assign(
temp,
ty.into_base(),
instr,
)));
}

/// Returns true if the block's last instruction is a jump
pub fn jumps(&self) -> bool {
let last = self.statements.last();
let last = self.items.last();

if let Some(Statement::Volatile(instr)) = last {
if let Some(BlockItem::Statement(Statement::Volatile(instr))) = last {
matches!(instr, Instr::Ret(_) | Instr::Jmp(_) | Instr::Jnz(..))
} else {
false
Expand All @@ -423,7 +447,7 @@ impl fmt::Display for Block<'_> {
write!(
f,
"{}",
self.statements
self.items
.iter()
.map(|instr| format!("\t{}", instr))
.collect::<Vec<String>>()
Expand Down Expand Up @@ -472,7 +496,7 @@ impl<'a> Function<'a> {
pub fn add_block(&mut self, label: impl Into<String>) -> &mut Block<'a> {
self.blocks.push(Block {
label: label.into(),
statements: Vec::new(),
items: Vec::new(),
});
self.blocks.last_mut().unwrap()
}
Expand Down
20 changes: 12 additions & 8 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn qbe_value() {
fn block() {
let blk = Block {
label: "start".into(),
statements: vec![Statement::Volatile(Instr::Ret(None))],
items: vec![BlockItem::Statement(Statement::Volatile(Instr::Ret(None)))],
};

let formatted = format!("{}", blk);
Expand All @@ -35,19 +35,23 @@ fn block() {

let blk = Block {
label: "start".into(),
statements: vec![
Statement::Assign(
items: vec![
BlockItem::Comment("Comment".into()),
BlockItem::Statement(Statement::Assign(
Value::Temporary("foo".into()),
Type::Word,
Instr::Add(Value::Const(2), Value::Const(2)),
),
Statement::Volatile(Instr::Ret(Some(Value::Temporary("foo".into())))),
)),
BlockItem::Statement(Statement::Volatile(Instr::Ret(Some(Value::Temporary(
"foo".into(),
))))),
],
};

let formatted = format!("{}", blk);
let mut lines = formatted.lines();
assert_eq!(lines.next().unwrap(), "@start");
assert_eq!(lines.next().unwrap(), "\t# Comment");
assert_eq!(lines.next().unwrap(), "\t%foo =w add 2, 2");
assert_eq!(lines.next().unwrap(), "\tret %foo");
}
Expand All @@ -56,11 +60,11 @@ fn block() {
fn instr_blit() {
let blk = Block {
label: "start".into(),
statements: vec![Statement::Volatile(Instr::Blit(
items: vec![BlockItem::Statement(Statement::Volatile(Instr::Blit(
Value::Temporary("src".into()),
Value::Temporary("dst".into()),
4,
))],
)))],
};

let formatted = format!("{}", blk);
Expand All @@ -78,7 +82,7 @@ fn function() {
arguments: Vec::new(),
blocks: vec![Block {
label: "start".into(),
statements: vec![Statement::Volatile(Instr::Ret(None))],
items: vec![BlockItem::Statement(Statement::Volatile(Instr::Ret(None)))],
}],
};

Expand Down

0 comments on commit d73a3bb

Please sign in to comment.