diff --git a/src/fox32.pest b/src/fox32.pest index 8a9ca4f..e7fee2d 100644 --- a/src/fox32.pest +++ b/src/fox32.pest @@ -2,7 +2,7 @@ WHITESPACE = _{ " " | "\t" | "\n" | "\r" | "\x0B" | "\x0C" | "\xA0" | SPACE_SEPA COMMENT = _{ ";" ~ (!"\n" ~ ANY)* } assembly = { - SOI ~ (origin | include_bin | data | constant | label | instruction)* ~ EOI + SOI ~ (origin | include_bin_optional | include_bin | data | constant | label | instruction)* ~ EOI } origin = { @@ -13,6 +13,7 @@ origin_padding = { "org.pad" ~ operand_value } origin_no_padding = { "org" ~ operand_value } include_bin = { "#include_bin" ~ immediate_str } +include_bin_optional = { "#include_bin_optional" ~ immediate_str } data = { data_byte | diff --git a/src/main.rs b/src/main.rs index f6fd1b5..690c47d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -516,18 +516,23 @@ fn include_text_file(line_number: usize, text: &str, input_file: String) -> Stri final_file } -fn include_binary_file(pair: pest::iterators::Pair) -> AstNode { +fn include_binary_file(pair: pest::iterators::Pair, optional: bool) -> AstNode { let path_string = pair.into_inner().next().unwrap().as_str().trim(); - //let path = canonicalize(path_string).expect(&format!("failed to include file \"{}\"", path_string)); let mut source_path = SOURCE_PATH.lock().unwrap().clone(); source_path.push(path_string); println!("Including file as binary data: {:#?}", source_path.file_name().expect("invalid filename")); - let binary = read(source_path).expect("failed to include file"); + let binary = read(&source_path); + if binary.is_err() && optional { + println!("Optional include was not found: {:#?}", source_path.file_name().expect("invalid filename")); + return AstNode::IncludedBinary(vec![]); + } else if binary.is_err() { + panic!("failed to include file"); + } - AstNode::IncludedBinary(binary) + AstNode::IncludedBinary(binary.unwrap()) } fn parse(source: &str) -> Result, Error> { @@ -570,7 +575,8 @@ fn build_ast_from_expression(pair: pest::iterators::Pair) -> AstNode { Rule::label => parse_label(inner_pair.next().unwrap(), inner_pair.next()), Rule::data => parse_data(inner_pair.next().unwrap()), Rule::origin => parse_origin(inner_pair.next().unwrap()), - Rule::include_bin => include_binary_file(inner_pair.next().unwrap()), + Rule::include_bin => include_binary_file(inner_pair.next().unwrap(), false), + Rule::include_bin_optional => include_binary_file(inner_pair.next().unwrap(), true), _ => todo!("{:#?}", pair_rule), } }