Skip to content

Commit

Permalink
Add operators to Byte and Bool (#655)
Browse files Browse the repository at this point in the history
---------
Co-authored-by: John-John Tedro <[email protected]>
  • Loading branch information
bernsteining authored Nov 28, 2023
1 parent 4b611d2 commit 1fdc17f
Show file tree
Hide file tree
Showing 23 changed files with 185 additions and 121 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@1.71
- uses: dtolnay/rust-toolchain@1.74
with:
components: clippy
- uses: Swatinem/rust-cache@v2
Expand All @@ -41,8 +41,8 @@ jobs:
- uses: Swatinem/rust-cache@v2
- run: cargo doc -p rune --all-features
env:
RUSTFLAGS: --cfg docsrs
RUSTDOCFLAGS: --cfg docsrs
RUSTFLAGS: --cfg rune_docsrs
RUSTDOCFLAGS: --cfg rune_docsrs

basics:
runs-on: ubuntu-latest
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/site.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ jobs:
- run: cargo +nightly doc -p rune --all-features
env:
RUST_LOG: rune=info
RUSTFLAGS: --cfg docsrs
RUSTDOCFLAGS: --cfg docsrs
RUSTFLAGS: --cfg rune_docsrs
RUSTDOCFLAGS: --cfg rune_docsrs
- run: mv target/doc target/site/api
- uses: peaceiris/actions-gh-pages@v3
with:
Expand Down
2 changes: 1 addition & 1 deletion crates/rune/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,4 @@ trybuild = "1.0.80"

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "rune_docsrs"]
10 changes: 5 additions & 5 deletions crates/rune/src/internal_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ macro_rules! cfg_emit {
($($item:item)*) => {
$(
#[cfg(feature = "emit")]
#[cfg_attr(docsrs, doc(cfg(feature = "emit")))]
#[cfg_attr(rune_docsrs, doc(cfg(feature = "emit")))]
$item
)*
}
Expand All @@ -85,7 +85,7 @@ macro_rules! cfg_workspace {
($($item:item)*) => {
$(
#[cfg(feature = "workspace")]
#[cfg_attr(docsrs, doc(cfg(feature = "workspace")))]
#[cfg_attr(rune_docsrs, doc(cfg(feature = "workspace")))]
$item
)*
}
Expand All @@ -95,7 +95,7 @@ macro_rules! cfg_cli {
($($item:item)*) => {
$(
#[cfg(feature = "cli")]
#[cfg_attr(docsrs, doc(cfg(feature = "cli")))]
#[cfg_attr(rune_docsrs, doc(cfg(feature = "cli")))]
$item
)*
}
Expand All @@ -105,7 +105,7 @@ macro_rules! cfg_doc {
($($item:item)*) => {
$(
#[cfg(feature = "doc")]
#[cfg_attr(docsrs, doc(cfg(feature = "doc")))]
#[cfg_attr(rune_docsrs, doc(cfg(feature = "doc")))]
$item
)*
}
Expand All @@ -115,7 +115,7 @@ macro_rules! cfg_std {
($($item:item)*) => {
$(
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
#[cfg_attr(rune_docsrs, doc(cfg(feature = "std")))]
$item
)*
}
Expand Down
2 changes: 1 addition & 1 deletion crates/rune/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@
#![allow(clippy::type_complexity)]
#![allow(clippy::module_inception)]
#![allow(clippy::self_named_constructors)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(rune_docsrs, feature(doc_cfg))]

#[cfg(feature = "std")]
#[macro_use]
Expand Down
85 changes: 51 additions & 34 deletions crates/rune/src/runtime/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1342,42 +1342,12 @@ impl Vm {
VmResult::Ok(())
}

/// Internal impl of a numeric operation.
fn internal_infallible_bitwise(
&mut self,
protocol: Protocol,
integer_op: fn(i64, i64) -> i64,
lhs: InstAddress,
rhs: InstAddress,
) -> VmResult<()> {
let rhs = vm_try!(self.stack.address(rhs));
let lhs = vm_try!(self.stack.address(lhs));

let (lhs, rhs) = match (lhs, rhs) {
(Value::Integer(lhs), Value::Integer(rhs)) => {
vm_try!(self.stack.push(Value::from(integer_op(lhs, rhs))));
return VmResult::Ok(());
}
(lhs, rhs) => (lhs, rhs),
};

if let CallResult::Unsupported(lhs) = vm_try!(self.call_instance_fn(lhs, protocol, (&rhs,)))
{
return err(VmErrorKind::UnsupportedBinaryOperation {
op: protocol.name,
lhs: vm_try!(lhs.type_info()),
rhs: vm_try!(rhs.type_info()),
});
}

VmResult::Ok(())
}

/// Internal impl of a numeric operation.
fn internal_infallible_bitwise_bool(
&mut self,
protocol: Protocol,
integer_op: fn(i64, i64) -> i64,
byte_op: fn(u8, u8) -> u8,
bool_op: fn(bool, bool) -> bool,
lhs: InstAddress,
rhs: InstAddress,
Expand All @@ -1390,6 +1360,10 @@ impl Vm {
vm_try!(self.stack.push(Value::from(integer_op(lhs, rhs))));
return VmResult::Ok(());
}
(Value::Byte(lhs), Value::Byte(rhs)) => {
vm_try!(self.stack.push(Value::from(byte_op(lhs, rhs))));
return VmResult::Ok(());
}
(Value::Bool(lhs), Value::Bool(rhs)) => {
vm_try!(self.stack.push(Value::from(bool_op(lhs, rhs))));
return VmResult::Ok(());
Expand All @@ -1414,6 +1388,8 @@ impl Vm {
target: InstTarget,
protocol: Protocol,
integer_op: fn(&mut i64, i64),
byte_op: fn(&mut u8, u8),
bool_op: fn(&mut bool, bool),
) -> VmResult<()> {
let lhs;
let mut guard;
Expand All @@ -1424,6 +1400,14 @@ impl Vm {
integer_op(lhs, rhs);
return VmResult::Ok(());
}
(Value::Byte(lhs), Value::Byte(rhs)) => {
byte_op(lhs, rhs);
return VmResult::Ok(());
}
(Value::Bool(lhs), Value::Bool(rhs)) => {
bool_op(lhs, rhs);
return VmResult::Ok(());
}
(lhs, rhs) => TargetFallback::Value(lhs.clone(), rhs),
},
TargetValue::Fallback(fallback) => fallback,
Expand All @@ -1437,6 +1421,7 @@ impl Vm {
protocol: Protocol,
error: fn() -> VmErrorKind,
integer_op: fn(i64, i64) -> Option<i64>,
byte_op: fn(u8, i64) -> Option<u8>,
lhs: InstAddress,
rhs: InstAddress,
) -> VmResult<()> {
Expand All @@ -1449,6 +1434,11 @@ impl Vm {
vm_try!(self.stack.push(Value::from(integer)));
return VmResult::Ok(());
}
(Value::Byte(lhs), Value::Integer(rhs)) => {
let byte = vm_try!(byte_op(lhs, rhs).ok_or_else(error));
vm_try!(self.stack.push(Value::from(byte)));
return VmResult::Ok(());
}
(lhs, rhs) => (lhs, rhs),
};

Expand All @@ -1470,6 +1460,7 @@ impl Vm {
protocol: Protocol,
error: fn() -> VmErrorKind,
integer_op: fn(i64, i64) -> Option<i64>,
byte_op: fn(u8, i64) -> Option<u8>,
) -> VmResult<()> {
let lhs;
let mut guard;
Expand All @@ -1481,6 +1472,11 @@ impl Vm {
*lhs = out;
return VmResult::Ok(());
}
(Value::Byte(lhs), Value::Integer(rhs)) => {
let out = vm_try!(byte_op(*lhs, rhs).ok_or_else(error));
*lhs = out;
return VmResult::Ok(());
}
(lhs, rhs) => TargetFallback::Value(lhs.clone(), rhs),
},
TargetValue::Fallback(fallback) => fallback,
Expand Down Expand Up @@ -1712,6 +1708,7 @@ impl Vm {
let value = match value {
Value::Bool(value) => Value::from(!value),
Value::Integer(value) => Value::from(!value),
Value::Byte(value) => Value::from(!value),
other => {
let operand = vm_try!(other.type_info());
return err(VmErrorKind::UnsupportedUnaryOperation { op: "!", operand });
Expand Down Expand Up @@ -1797,6 +1794,7 @@ impl Vm {
vm_try!(self.internal_infallible_bitwise_bool(
Protocol::BIT_AND,
i64::bitand,
u8::bitand,
bool::bitand,
lhs,
rhs,
Expand All @@ -1807,6 +1805,7 @@ impl Vm {
vm_try!(self.internal_infallible_bitwise_bool(
Protocol::BIT_XOR,
i64::bitxor,
u8::bitxor,
bool::bitxor,
lhs,
rhs,
Expand All @@ -1817,6 +1816,7 @@ impl Vm {
vm_try!(self.internal_infallible_bitwise_bool(
Protocol::BIT_OR,
i64::bitor,
u8::bitor,
bool::bitor,
lhs,
rhs,
Expand All @@ -1827,12 +1827,20 @@ impl Vm {
Protocol::SHL,
|| VmErrorKind::Overflow,
|a, b| a.checked_shl(u32::try_from(b).ok()?),
|a, b| a.checked_shl(u32::try_from(b).ok()?),
lhs,
rhs,
));
}
InstOp::Shr => {
vm_try!(self.internal_infallible_bitwise(Protocol::SHR, ops::Shr::shr, lhs, rhs));
vm_try!(self.internal_bitwise(
Protocol::SHR,
|| VmErrorKind::Underflow,
|a, b| a.checked_shr(u32::try_from(b).ok()?),
|a, b| a.checked_shr(u32::try_from(b).ok()?),
lhs,
rhs
));
}
InstOp::Gt => {
vm_try!(self.internal_boolean_ops(
Expand Down Expand Up @@ -1958,20 +1966,26 @@ impl Vm {
target,
Protocol::BIT_AND_ASSIGN,
ops::BitAndAssign::bitand_assign,
ops::BitAndAssign::bitand_assign,
ops::BitAndAssign::bitand_assign,
));
}
InstAssignOp::BitXor => {
vm_try!(self.internal_infallible_bitwise_assign(
target,
Protocol::BIT_XOR_ASSIGN,
ops::BitXorAssign::bitxor_assign,
ops::BitXorAssign::bitxor_assign,
ops::BitXorAssign::bitxor_assign,
));
}
InstAssignOp::BitOr => {
vm_try!(self.internal_infallible_bitwise_assign(
target,
Protocol::BIT_OR_ASSIGN,
ops::BitOrAssign::bitor_assign,
ops::BitOrAssign::bitor_assign,
ops::BitOrAssign::bitor_assign,
));
}
InstAssignOp::Shl => {
Expand All @@ -1980,13 +1994,16 @@ impl Vm {
Protocol::SHL_ASSIGN,
|| VmErrorKind::Overflow,
|a, b| a.checked_shl(u32::try_from(b).ok()?),
|a, b| a.checked_shl(u32::try_from(b).ok()?),
));
}
InstAssignOp::Shr => {
vm_try!(self.internal_infallible_bitwise_assign(
vm_try!(self.internal_bitwise_assign(
target,
Protocol::SHR_ASSIGN,
ops::ShrAssign::shr_assign,
|| VmErrorKind::Underflow,
|a, b| a.checked_shr(u32::try_from(b).ok()?),
|a, b| a.checked_shr(u32::try_from(b).ok()?),
));
}
}
Expand Down
34 changes: 28 additions & 6 deletions crates/rune/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,17 @@ macro_rules! expected {
"Did not match expected {}\nExpected: {}\n Actual: {:?}",
$name,
stringify!($expected),
$actual
$actual,
)
};

($name:literal, $expected:pat, $actual:expr, $extra:expr) => {
panic!(
"Did not match expected {}\nExpected: {}\n Actual: {:?}\n{}",
$name,
stringify!($expected),
$actual,
$extra,
)
};
}
Expand All @@ -211,15 +221,27 @@ macro_rules! expected {
macro_rules! rune {
($($tt:tt)*) => {{
let context = $crate::Context::with_default_modules().expect("Failed to build context");
$crate::tests::run(&context, stringify!($($tt)*), ["main"], ()).expect("Program ran unsuccessfully")

match $crate::tests::run(&context, stringify!($($tt)*), ["main"], ()) {
Ok(output) => output,
Err(error) => {
panic!("Program failed to run:\n{}\n{}", error, stringify!($source));
}
}
}};
}

/// Run the given program and return the expected type from it.
macro_rules! rune_s {
($source:expr) => {{
let context = $crate::Context::with_default_modules().expect("Failed to build context");
$crate::tests::run(&context, $source, ["main"], ()).expect("Program ran unsuccessfully")

match $crate::tests::run(&context, $source, ["main"], ()) {
Ok(output) => output,
Err(error) => {
panic!("Program failed to run:\n{}\n{}", error, $source);
}
}
}};
}

Expand Down Expand Up @@ -250,21 +272,21 @@ macro_rules! assert_vm_error {
let e = match $crate::tests::run_helper::<_, _, $ty>(&context, &mut sources, &mut diagnostics, ["main"], ()) {
Err(e) => e,
actual => {
expected!("program error", Err(e), actual)
expected!("program error", Err(e), actual, $source)
}
};

let e = match e {
$crate::tests::TestError::VmError(e) => e,
actual => {
expected!("vm error", VmError(e), actual)
expected!("vm error", VmError(e), actual, $source)
}
};

match e.into_kind() {
$pat => $cond,
actual => {
expected!("error", $pat, actual)
expected!("error", $pat, actual, $source)
}
}
}};
Expand Down
2 changes: 1 addition & 1 deletion crates/rune/src/tests/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use ErrorKind::*;

#[test]
fn basic_use() {
let _: () = rune! {
rune! {
mod private {
#[test]
fn test_case() {
Expand Down
Loading

0 comments on commit 1fdc17f

Please sign in to comment.