Skip to content

Commit 734b79e

Browse files
Ryan1729udoprog
authored andcommitted
Implement bitwise operations
1 parent f448c78 commit 734b79e

File tree

4 files changed

+57
-2
lines changed

4 files changed

+57
-2
lines changed

crates/rune/src/compile/ir.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ mod eval;
88
mod interpreter;
99
pub(crate) mod scopes;
1010

11-
use core::ops::{AddAssign, MulAssign, ShlAssign, ShrAssign, SubAssign};
11+
use core::ops::{
12+
AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, MulAssign, ShlAssign, ShrAssign, SubAssign,
13+
};
1214

1315
use crate as rune;
1416
use crate::alloc::prelude::*;
@@ -503,6 +505,12 @@ pub(crate) enum IrBinaryOp {
503505
Gt,
504506
/// `>=`,
505507
Gte,
508+
/// `&`.
509+
BitAnd,
510+
/// `^`.
511+
BitXor,
512+
/// `|`.
513+
BitOr,
506514
}
507515

508516
/// An assign operation.
@@ -521,6 +529,12 @@ pub(crate) enum IrAssignOp {
521529
Shl,
522530
/// `>>=`.
523531
Shr,
532+
/// `&=`.
533+
BitAnd,
534+
/// `^=`.
535+
BitXor,
536+
/// `|=`.
537+
BitOr,
524538
}
525539

526540
impl IrAssignOp {
@@ -578,6 +592,15 @@ impl IrAssignOp {
578592

579593
target.shr_assign(operand);
580594
}
595+
IrAssignOp::BitAnd => {
596+
target.bitand_assign(operand);
597+
}
598+
IrAssignOp::BitXor => {
599+
target.bitxor_assign(operand);
600+
}
601+
IrAssignOp::BitOr => {
602+
target.bitor_assign(operand);
603+
}
581604
}
582605

583606
Ok(())

crates/rune/src/compile/ir/compiler.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ fn expr_binary(
156156
ast::BinOp::DivAssign(..) => ir::IrAssignOp::Div,
157157
ast::BinOp::ShlAssign(..) => ir::IrAssignOp::Shl,
158158
ast::BinOp::ShrAssign(..) => ir::IrAssignOp::Shr,
159+
ast::BinOp::BitAndAssign(..) => ir::IrAssignOp::BitAnd,
160+
ast::BinOp::BitXorAssign(..) => ir::IrAssignOp::BitXor,
161+
ast::BinOp::BitOrAssign(..) => ir::IrAssignOp::BitOr,
159162
_ => return Err(compile::Error::msg(hir.op, "op not supported yet")),
160163
};
161164

@@ -187,6 +190,9 @@ fn expr_binary(
187190
ast::BinOp::Eq(..) => ir::IrBinaryOp::Eq,
188191
ast::BinOp::Gt(..) => ir::IrBinaryOp::Gt,
189192
ast::BinOp::Gte(..) => ir::IrBinaryOp::Gte,
193+
ast::BinOp::BitAnd(..) => ir::IrBinaryOp::BitAnd,
194+
ast::BinOp::BitXor(..) => ir::IrBinaryOp::BitXor,
195+
ast::BinOp::BitOr(..) => ir::IrBinaryOp::BitOr,
190196
_ => return Err(compile::Error::msg(hir.op, "op not supported yet")),
191197
};
192198

crates/rune/src/compile/ir/eval.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use core::ops::{Add, Mul, Shl, Shr, Sub};
1+
use core::ops::{Add, BitAnd, BitOr, BitXor, Mul, Shl, Shr, Sub};
22

33
use crate::alloc::fmt::TryWrite;
44
use crate::alloc::prelude::*;
@@ -116,6 +116,15 @@ fn eval_ir_binary(
116116
ir::IrBinaryOp::Eq => break 'out Inline::Bool(a == b),
117117
ir::IrBinaryOp::Gt => break 'out Inline::Bool(a > b),
118118
ir::IrBinaryOp::Gte => break 'out Inline::Bool(a >= b),
119+
ir::IrBinaryOp::BitAnd => {
120+
break 'out Inline::Signed(a.bitand(b));
121+
}
122+
ir::IrBinaryOp::BitXor => {
123+
break 'out Inline::Signed(a.bitxor(b));
124+
}
125+
ir::IrBinaryOp::BitOr => {
126+
break 'out Inline::Signed(a.bitor(b));
127+
}
119128
},
120129
(Inline::Float(a), Inline::Float(b)) => {
121130
#[allow(clippy::float_cmp)]

crates/rune/tests/bitwise_ops.rn

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#[test]
2+
fn bitwise_ops() {
3+
assert_eq!(0b1100 & 0b1010, 0b1000);
4+
let anded = 0b0101;
5+
anded &= 0b0011;
6+
assert_eq!(anded, 0b0001);
7+
8+
assert_eq!(0b1100 ^ 0b1010, 0b0110);
9+
let xored = 0b0101;
10+
xored ^= 0b0011;
11+
assert_eq!(xored, 0b0110);
12+
13+
assert_eq!(0b1100 | 0b1010, 0b1110);
14+
let ored = 0b0101;
15+
ored |= 0b0011;
16+
assert_eq!(ored, 0b0111);
17+
}

0 commit comments

Comments
 (0)