diff options
author | Ben Bridle <ben@derelict.engineering> | 2025-04-26 09:09:59 +1200 |
---|---|---|
committer | Ben Bridle <ben@derelict.engineering> | 2025-04-26 09:09:59 +1200 |
commit | 4b53479153806e3a1e7a4944313f77dc262117b2 (patch) | |
tree | 27feabd2ff2eba283a1e6e8022139c12161ab25e | |
parent | 8c30c7fbe9b869fb78765a4b7994858f0c8f8182 (diff) | |
download | torque-asm-4b53479153806e3a1e7a4944313f77dc262117b2.zip |
Implement <tal> operator for expressions
The <tal> operator returns the number of set bits in the binary
representation of an integer. For negative numbers, only a single sign
bit is counted in the result.
-rw-r--r-- | src/types/expression_stack.rs | 8 | ||||
-rw-r--r-- | src/types/operator.rs | 3 |
2 files changed, 11 insertions, 0 deletions
diff --git a/src/types/expression_stack.rs b/src/types/expression_stack.rs index d14d808..8e1c87d 100644 --- a/src/types/expression_stack.rs +++ b/src/types/expression_stack.rs @@ -62,6 +62,7 @@ impl ExpressionStack { Operator::BitXor => { pop!(b); pop!(a); push!(a ^ b) }, Operator::BitNot => { pop!(a); push!(!a) }, Operator::Length => { pop!(a); push!(width(a) as isize) }, + Operator::Tally => { pop!(a); push!(tally(a) as isize) }, } return Ok(()); } @@ -76,6 +77,13 @@ pub fn width(value: isize) -> u32 { } } +pub fn tally(value: isize) -> u32 { + let width = width(value); + let mask = 2i32.pow(width) -1; + let value = (value as usize) & (mask as usize); + return value.count_ones(); +} + pub enum StackError { Underflow, MultipleReturnValues, diff --git a/src/types/operator.rs b/src/types/operator.rs index af607e3..d5b5e94 100644 --- a/src/types/operator.rs +++ b/src/types/operator.rs @@ -19,6 +19,7 @@ pub enum Operator { BitXor, BitNot, Length, + Tally, } impl Operator { @@ -57,6 +58,7 @@ impl Operator { "<xor>" => Some(Operator::BitXor), "<not>" => Some(Operator::BitNot), "<len>" => Some(Operator::Length), + "<tal>" => Some(Operator::Tally), _ => None, } } @@ -84,6 +86,7 @@ impl std::fmt::Display for Operator { Operator::BitXor => "<xor>", Operator::BitNot => "<not>", Operator::Length => "<len>", + Operator::Tally => "<tal>", }; write!(f, "{string}") } |