Skip to content

Commit

Permalink
allow zero-sized slices
Browse files Browse the repository at this point in the history
  • Loading branch information
hlorenzi committed Apr 18, 2021
1 parent a4e6fce commit a3921b4
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 24 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "customasm"
version = "0.11.6"
version = "0.11.7"
edition = "2018"
authors = ["hlorenzi <https://hlorenzi.com>"]
description = "An assembler for custom, user-defined instruction sets!"
Expand Down
4 changes: 2 additions & 2 deletions src/asm/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1257,9 +1257,9 @@ impl State
else
{
result = result.concat(
(result.size.unwrap() - 1, 0),
(result.size.unwrap(), 0),
&bigint,
(size - 1, 0));
(size, 0));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/expr/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ impl expr::Expr

match (lhs.size, rhs.size)
{
(Some(lhs_width), Some(rhs_width)) => Ok(expr::Value::make_integer(lhs.concat((lhs_width - 1, 0), &rhs, (rhs_width - 1, 0)))),
(Some(lhs_width), Some(rhs_width)) => Ok(expr::Value::make_integer(lhs.concat((lhs_width, 0), &rhs, (rhs_width, 0)))),
(None, _) => Err(report.error_span("argument to concatenation with unspecified size", &lhs_expr.span())),
(_, None) => Err(report.error_span("argument to concatenation with unspecified size", &rhs_expr.span()))
}
Expand Down
6 changes: 3 additions & 3 deletions src/expr/inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl expr::Expr
{
&expr::Expr::Literal(_, expr::Value::Integer(util::BigInt { size: Some(size), .. })) =>
{
Some((size - 1, 0))
Some((size, 0))
}

&expr::Expr::BinaryOp(_, _, expr::BinaryOp::Concat, ref lhs, ref rhs) =>
Expand All @@ -47,7 +47,7 @@ impl expr::Expr
if lhs_width.is_none() || rhs_width.is_none()
{ return None; }

Some((lhs_width.unwrap() + rhs_width.unwrap() - 1, 0))
Some((lhs_width.unwrap() + rhs_width.unwrap(), 0))
}

&expr::Expr::BitSlice(_, _, left, right, _) => Some((left, right)),
Expand All @@ -64,7 +64,7 @@ impl expr::Expr
if true_width.unwrap() != false_width.unwrap()
{ return None; }

Some((true_width.unwrap() - 1, 0))
Some((true_width.unwrap(), 0))
}

&expr::Expr::Block(_, ref exprs) =>
Expand Down
13 changes: 2 additions & 11 deletions src/expr/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ impl<'a, 'parser> ExpressionParser<'a, 'parser>
return Err(());
}

Ok(expr::Expr::BitSlice(span, slice_span, leftmost, rightmost, Box::new(inner)))
Ok(expr::Expr::BitSlice(span, slice_span, leftmost + 1, rightmost, Box::new(inner)))
}


Expand All @@ -321,16 +321,7 @@ impl<'a, 'parser> ExpressionParser<'a, 'parser>
let span = inner.span().join(&tk_size.span);
let size_span = tk_grave.span.join(&tk_size.span);

if size < 1
{
if let Some(ref report) = self.parser.report
{
report.error_span("invalid size specifier", &size_span);
return Err(());
}
}

Ok(expr::Expr::BitSlice(span, size_span, size - 1, 0, Box::new(inner)))
Ok(expr::Expr::BitSlice(span, size_span, size, 0, Box::new(inner)))
}


Expand Down
13 changes: 11 additions & 2 deletions src/test/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ fn test_ops_arithmetic()
test("-4 >> 1", Pass(expr::Value::make_integer(util::BigInt::new(-2, None))));
test("-4 >> 2", Pass(expr::Value::make_integer(util::BigInt::new(-1, None))));
test("-4 >> 3", Pass(expr::Value::make_integer(util::BigInt::new(-1, None))));

test("123`0 + 2", Pass(expr::Value::make_integer(util::BigInt::new(2, None))));
}


Expand Down Expand Up @@ -207,6 +209,11 @@ fn test_ops_slice()
test("0xff`8", Pass(expr::Value::make_integer(util::BigInt::new(0xff, Some(8)))));
test("0x101`8", Pass(expr::Value::make_integer(util::BigInt::new(0x1, Some(8)))));

test("0`0", Pass(expr::Value::make_integer(util::BigInt::new(0, Some(0)))));
test("0x0`0", Pass(expr::Value::make_integer(util::BigInt::new(0, Some(0)))));
test("0x100`0", Pass(expr::Value::make_integer(util::BigInt::new(0, Some(0)))));
test("0xfff`0", Pass(expr::Value::make_integer(util::BigInt::new(0, Some(0)))));

test("0x00[0:0]", Pass(expr::Value::make_integer(util::BigInt::new(0, Some(1)))));
test("0x0f[0:0]", Pass(expr::Value::make_integer(util::BigInt::new(1, Some(1)))));
test("0xff[0:0]", Pass(expr::Value::make_integer(util::BigInt::new(1, Some(1)))));
Expand Down Expand Up @@ -238,8 +245,6 @@ fn test_ops_slice()
test(" 1[1000:1000]", Pass(expr::Value::make_integer(util::BigInt::new(0, Some(1)))));
test("-1[1000:1000]", Pass(expr::Value::make_integer(util::BigInt::new(1, Some(1)))));

test("0x100`0", Fail(("test", 1, "invalid")));

test("0x00[0:7]", Fail(("test", 1, "invalid")));

test("0x00[0x1_ffff_ffff_ffff_ffff:7]", Fail(("test", 1, "large")));
Expand All @@ -253,6 +258,10 @@ fn test_ops_concat()
test("0x12`8 @ 0x34`8", Pass(expr::Value::make_integer(util::BigInt::new(0x1234, Some(16)))));
test("0x12`16 @ 0x34`16", Pass(expr::Value::make_integer(util::BigInt::new(0x120034, Some(32)))));

test("0`8 @ 0`0 @ 0`8", Pass(expr::Value::make_integer(util::BigInt::new(0, Some(16)))));
test("0x12`8 @ 0`0 @ 0x34`8", Pass(expr::Value::make_integer(util::BigInt::new(0x1234, Some(16)))));
test("0x12`16 @ 0`0 @ 0x34`16", Pass(expr::Value::make_integer(util::BigInt::new(0x120034, Some(32)))));

test("(6 + 6)[3:0] @ (5 + 5)[3:0]", Pass(expr::Value::make_integer(util::BigInt::new(0xca, Some(8)))));

test("4`6 @ 0`5", Pass(expr::Value::make_integer(util::BigInt::new(0b10000000, Some(11)))));
Expand Down
8 changes: 4 additions & 4 deletions src/util/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ impl BigInt

pub fn concat(&self, lhs_slice: (usize, usize), rhs: &BigInt, rhs_slice: (usize, usize)) -> BigInt
{
let lhs_size = lhs_slice.0 + 1 - lhs_slice.1;
let rhs_size = rhs_slice.0 + 1 - rhs_slice.1;
let lhs_size = lhs_slice.0 - lhs_slice.1;
let rhs_size = rhs_slice.0 - rhs_slice.1;
let lhs = self.slice(lhs_slice.0, lhs_slice.1).shl(rhs_size);
let rhs = rhs.slice(rhs_slice.0, rhs_slice.1);

Expand All @@ -209,12 +209,12 @@ impl BigInt
use num_traits::One;

let mut mask = num_bigint::BigInt::zero();
for _ in 0..(left - right + 1)
for _ in 0..(left - right)
{ mask = (mask << 1) + num_bigint::BigInt::one(); }

let shifted_mask = BigInt::new(mask, None).shl(right);
let mut result = (self & &shifted_mask).shr(right);
result.size = Some(left + 1 - right);
result.size = Some(left - right);
result
}

Expand Down

0 comments on commit a3921b4

Please sign in to comment.