diff --git a/src/fox32.pest b/src/fox32.pest index eccf523..41b920f 100644 --- a/src/fox32.pest +++ b/src/fox32.pest @@ -18,12 +18,14 @@ data = { data_byte | data_half | data_word | - data_str + data_str | + data_fill } data_byte = { "data.8" ~ operand_value } data_half = { "data.16" ~ operand_value } data_word = { "data.32" ~ operand_value } data_str = { "data.str" ~ immediate_str } +data_fill = { "data.fill" ~ operand_value ~ "," ~ operand_value } constant = { "const" ~ constant_name ~ operand_value } constant_name = ${label_name ~ ":"} diff --git a/src/main.rs b/src/main.rs index 5f119db..85dca82 100644 --- a/src/main.rs +++ b/src/main.rs @@ -288,6 +288,10 @@ enum AstNode { DataHalf(u16), DataWord(u32), DataStr(String), + DataFill { + value: u8, + size: u32, + }, IncludedBinary(Vec), @@ -363,6 +367,9 @@ fn main() { let difference = (origin_address - current_address) as usize; current_address = origin_address; instructions.push(vec![0; difference].into()); + } else if let AstNode::DataFill {value, size} = node { + current_address += size; + instructions.push(vec![value; size as usize].into()); } else if let AstNode::IncludedBinary(binary_vec) = node { current_address += binary_vec.len() as u32; instructions.push(binary_vec.into()); @@ -630,6 +637,25 @@ fn parse_data(pair: pest::iterators::Pair) -> AstNode { let string = pair.into_inner().next().unwrap().into_inner().next().unwrap().as_str(); AstNode::DataStr(string.to_string()) }, + Rule::data_fill => { + let value = { + let ast = parse_operand(pair.clone().into_inner().next().unwrap(), false); + if let AstNode::Immediate32(word) = ast { + word as u8 + } else { + unreachable!() + } + }; + let size = { + let ast = parse_operand(pair.into_inner().nth(1).unwrap(), false); + if let AstNode::Immediate32(word) = ast { + word + } else { + unreachable!() + } + }; + AstNode::DataFill {value, size} + }, _ => panic!("Unsupported data: {}", pair.as_str()), } }