1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
use crate::*; impl expr::Expr { pub fn width(&self) -> Option<usize> { if let Some(slice) = self.slice() { Some(slice.0 + 1 - slice.1) } else { None } } pub fn size(&self) -> Option<usize> { if let Some(slice) = self.slice() { Some(slice.0 + 1 - slice.1) } else { None } } pub fn has_size(&self) -> bool { if let Some(_) = self.slice() { true } else { false } } pub fn slice(&self) -> Option<(usize, usize)> { match self { &expr::Expr::Literal(_, expr::Value::Integer(util::BigInt { size: Some(size), .. })) => { Some((size - 1, 0)) } &expr::Expr::BinaryOp(_, _, expr::BinaryOp::Concat, ref lhs, ref rhs) => { let lhs_width = lhs.width(); let rhs_width = rhs.width(); if lhs_width.is_none() || rhs_width.is_none() { return None; } Some((lhs_width.unwrap() + rhs_width.unwrap() - 1, 0)) } &expr::Expr::BitSlice(_, _, left, right, _) => Some((left, right)), &expr::Expr::SoftSlice(_, _, left, right, _) => Some((left, right)), &expr::Expr::TernaryOp(_, _, ref true_branch, ref false_branch) => { let true_width = true_branch.width(); let false_width = false_branch.width(); if true_width.is_none() || false_width.is_none() { return None; } if true_width.unwrap() != false_width.unwrap() { return None; } Some((true_width.unwrap() - 1, 0)) } &expr::Expr::Block(_, ref exprs) => { match exprs.last() { None => None, Some(expr) => expr.slice() } } _ => None } } pub fn returned_value_span(&self) -> diagn::Span { match self { &expr::Expr::Block(ref span, ref exprs) => { match exprs.last() { None => span.clone(), Some(expr) => expr.returned_value_span() } } _ => self.span() } } }