@@ -57,10 +57,18 @@ struct CompileConstantEvaluator<'a> {
5757impl CompileConstantEvaluator < ' _ > {
5858 fn evaluate_expression ( & mut self , expression : & input_ir:: Expression ) -> Option < ConstantValue > {
5959 match expression {
60- input_ir:: Expression :: BitwiseOrExpression ( _bitwise_or_expression) => todo ! ( ) ,
61- input_ir:: Expression :: BitwiseXorExpression ( _bitwise_xor_expression) => todo ! ( ) ,
62- input_ir:: Expression :: BitwiseAndExpression ( _bitwise_and_expression) => todo ! ( ) ,
63- input_ir:: Expression :: ShiftExpression ( _shift_expression) => todo ! ( ) ,
60+ input_ir:: Expression :: BitwiseOrExpression ( bitwise_or_expression) => {
61+ self . evaluate_bitwise_or_expression ( bitwise_or_expression)
62+ }
63+ input_ir:: Expression :: BitwiseXorExpression ( bitwise_xor_expression) => {
64+ self . evaluate_bitwise_xor_expression ( bitwise_xor_expression)
65+ }
66+ input_ir:: Expression :: BitwiseAndExpression ( bitwise_and_expression) => {
67+ self . evaluate_bitwise_and_expression ( bitwise_and_expression)
68+ }
69+ input_ir:: Expression :: ShiftExpression ( shift_expression) => {
70+ self . evaluate_shift_expression ( shift_expression)
71+ }
6472 input_ir:: Expression :: AdditiveExpression ( additive_expression) => {
6573 self . evaluate_additive_expression ( additive_expression)
6674 }
@@ -86,12 +94,75 @@ impl CompileConstantEvaluator<'_> {
8694 self . evaluate_tuple_expression ( tuple_expression)
8795 }
8896 _ => {
89- // all other variants of expression cannot be evaluated at compile time
97+ // all other variants of expression cannot be evaluated at
98+ // compile time, or are not relevant for computing constant
99+ // integers (eg. string literals)
90100 None
91101 }
92102 }
93103 }
94104
105+ fn evaluate_bitwise_or_expression (
106+ & mut self ,
107+ bitwise_or_expression : & input_ir:: BitwiseOrExpression ,
108+ ) -> Option < ConstantValue > {
109+ let lhs = self . evaluate_expression ( & bitwise_or_expression. left_operand ) ?;
110+ let rhs = self . evaluate_expression ( & bitwise_or_expression. right_operand ) ?;
111+ match ( lhs, rhs) {
112+ ( ConstantValue :: Integer ( lhs) , ConstantValue :: Integer ( rhs) ) => {
113+ Some ( ConstantValue :: Integer ( lhs | rhs) )
114+ }
115+ }
116+ }
117+
118+ fn evaluate_bitwise_xor_expression (
119+ & mut self ,
120+ bitwise_xor_expression : & input_ir:: BitwiseXorExpression ,
121+ ) -> Option < ConstantValue > {
122+ let lhs = self . evaluate_expression ( & bitwise_xor_expression. left_operand ) ?;
123+ let rhs = self . evaluate_expression ( & bitwise_xor_expression. right_operand ) ?;
124+ match ( lhs, rhs) {
125+ ( ConstantValue :: Integer ( lhs) , ConstantValue :: Integer ( rhs) ) => {
126+ Some ( ConstantValue :: Integer ( lhs ^ rhs) )
127+ }
128+ }
129+ }
130+
131+ fn evaluate_bitwise_and_expression (
132+ & mut self ,
133+ bitwise_and_expression : & input_ir:: BitwiseAndExpression ,
134+ ) -> Option < ConstantValue > {
135+ let lhs = self . evaluate_expression ( & bitwise_and_expression. left_operand ) ?;
136+ let rhs = self . evaluate_expression ( & bitwise_and_expression. right_operand ) ?;
137+ match ( lhs, rhs) {
138+ ( ConstantValue :: Integer ( lhs) , ConstantValue :: Integer ( rhs) ) => {
139+ Some ( ConstantValue :: Integer ( lhs & rhs) )
140+ }
141+ }
142+ }
143+
144+ fn evaluate_shift_expression (
145+ & mut self ,
146+ shift_expression : & input_ir:: ShiftExpression ,
147+ ) -> Option < ConstantValue > {
148+ let lhs = self . evaluate_expression ( & shift_expression. left_operand ) ?;
149+ let rhs = self . evaluate_expression ( & shift_expression. right_operand ) ?;
150+ match & shift_expression. operator . kind {
151+ TerminalKind :: LessThanLessThan => match ( lhs, rhs) {
152+ ( ConstantValue :: Integer ( lhs) , ConstantValue :: Integer ( rhs) ) => {
153+ Some ( ConstantValue :: Integer ( lhs << rhs. to_u32 ( ) ?) )
154+ }
155+ } ,
156+ TerminalKind :: GreaterThanGreaterThan => match ( lhs, rhs) {
157+ ( ConstantValue :: Integer ( lhs) , ConstantValue :: Integer ( rhs) ) => {
158+ Some ( ConstantValue :: Integer ( lhs >> rhs. to_u32 ( ) ?) )
159+ }
160+ } ,
161+ TerminalKind :: GreaterThanGreaterThanGreaterThan => None ,
162+ _ => unreachable ! ( "invalid operator in shift expression" ) ,
163+ }
164+ }
165+
95166 fn evaluate_additive_expression (
96167 & mut self ,
97168 additive_expression : & input_ir:: AdditiveExpression ,
@@ -327,6 +398,16 @@ mod tests {
327398 . is_some_and( |value| value == ConstantValue :: Integer ( 1 . to_bigint( ) . unwrap( ) ) ) ) ;
328399 assert ! ( eval_string( "2 ** 5" )
329400 . is_some_and( |value| value == ConstantValue :: Integer ( 32 . to_bigint( ) . unwrap( ) ) ) ) ;
401+ assert ! ( eval_string( "32 << 2" )
402+ . is_some_and( |value| value == ConstantValue :: Integer ( 128 . to_bigint( ) . unwrap( ) ) ) ) ;
403+ assert ! ( eval_string( "32 >> 2" )
404+ . is_some_and( |value| value == ConstantValue :: Integer ( 8 . to_bigint( ) . unwrap( ) ) ) ) ;
405+ assert ! ( eval_string( "32 | 16" )
406+ . is_some_and( |value| value == ConstantValue :: Integer ( 48 . to_bigint( ) . unwrap( ) ) ) ) ;
407+ assert ! ( eval_string( "15 ^ 31" )
408+ . is_some_and( |value| value == ConstantValue :: Integer ( 16 . to_bigint( ) . unwrap( ) ) ) ) ;
409+ assert ! ( eval_string( "15 & 31" )
410+ . is_some_and( |value| value == ConstantValue :: Integer ( 15 . to_bigint( ) . unwrap( ) ) ) ) ;
330411 }
331412
332413 #[ test]
0 commit comments