Skip to content

Commit

Permalink
Add support for including slices of binary files
Browse files Browse the repository at this point in the history
Adds 2 new forms of `incbin`:

- `incbin(relative_filename, start)`: includes `relative_filename` starting from offset `start`
- `incbin(relative_filename, start, size)`: includes `size` bytes from `relative_filename` starting from offset `start`

I'd also like to make `incbinstr` and `inchexstr` work similarly, but I'm not sure how to make it work.

When hlorenzi#191 gets merged, `ensure_inc_args` can be replaced with a call to `query.ensure_min_max_arg_number(1,3)?;`. Since I don't have that merged locally, I just wrote a quick and dirty function to do it.
  • Loading branch information
MineRobber9000 committed Dec 27, 2023
1 parent cbe63b6 commit 132a879
Showing 1 changed file with 69 additions and 4 deletions.
73 changes: 69 additions & 4 deletions src/asm/resolver/eval_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,26 @@ pub fn eval_fn(
}


fn ensure_inc_args(
query: &mut expr::EvalFunctionQuery
) -> Result<(),()>
{
if query.args.len() < 1 || query.args.len() > 3
{
query.report.error_span(
format!("function expected 1 to 3 arguments (got {})", query.args.len()),
query.span
);

Err(())
}
else
{
Ok(())
}
}


fn eval_builtin_incbin(
fileserver: &mut dyn util::FileServer,
_decls: &asm::ItemDecls,
Expand All @@ -123,7 +143,7 @@ fn eval_builtin_incbin(
query: &mut expr::EvalFunctionQuery)
-> Result<expr::Value, ()>
{
query.ensure_arg_number(1)?;
ensure_inc_args(query)?;

let relative_filename = query.args[0].value.expect_string(
query.report,
Expand All @@ -148,8 +168,53 @@ fn eval_builtin_incbin(
Some(query.args[0].span),
file_handle)?;

Ok(expr::Value::make_integer(
util::BigInt::from_bytes_be(&bytes)))
if query.args.len() == 1 {
Ok(expr::Value::make_integer(
util::BigInt::from_bytes_be(&bytes)))
} else if query.args.len() == 2 {
let start = query.args[1].value.expect_usize(query.report, query.args[1].span)?;

if start >= bytes.len() {
query.report.error_span(
format!("incbin starts after EOF ({} > {})",
start,
bytes.len()),
query.args[1].span
);
return Err(());
}

Ok(expr::Value::make_integer(
util::BigInt::from_bytes_be(&bytes[start..bytes.len()])))
} else {
let start = query.args[1].value.expect_usize(query.report, query.args[1].span)?;

let size = query.args[2].value.expect_usize(query.report, query.args[2].span)?;

if start >= bytes.len() {
query.report.error_span(
format!("incbin starts after EOF ({} > {})",
start,
bytes.len()),
query.args[1].span
);
return Err(());
}

if (start+size) > bytes.len() {
query.report.error_span(
format!("incbin ends after EOF ({} + {} > {})",
start,
size,
bytes.len()),
query.args[2].span
);
return Err(());
}

Ok(expr::Value::make_integer(
util::BigInt::from_bytes_be(&bytes[start..(start+size)])))
}
}


Expand Down Expand Up @@ -259,4 +324,4 @@ fn eval_builtin_incstr(
}

Ok(expr::Value::make_integer(bitvec.to_bigint()))
}
}

0 comments on commit 132a879

Please sign in to comment.