|
| 1 | +use crate::build::{ |
| 2 | + display::{ident::DisplayIdent, utils::DisplaySequence, Indent}, |
| 3 | + isa::Isa, |
| 4 | + op::Op, |
| 5 | +}; |
| 6 | +use core::fmt::{self, Display}; |
| 7 | + |
| 8 | +pub struct DisplayResultMut<T> { |
| 9 | + pub value: T, |
| 10 | + pub indent: Indent, |
| 11 | +} |
| 12 | + |
| 13 | +impl<T> DisplayResultMut<T> { |
| 14 | + pub fn new(value: T, indent: Indent) -> Self { |
| 15 | + Self { value, indent } |
| 16 | + } |
| 17 | +} |
| 18 | + |
| 19 | +impl Display for DisplayResultMut<&'_ Isa> { |
| 20 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 21 | + let indent = self.indent; |
| 22 | + let variants = DisplaySequence::new( |
| 23 | + "\n", |
| 24 | + self.value |
| 25 | + .ops |
| 26 | + .iter() |
| 27 | + .filter(|op| op.has_result()) |
| 28 | + .map(|op| DisplayResultMut::new(op, indent.inc_by(3))), |
| 29 | + ); |
| 30 | + write!( |
| 31 | + f, |
| 32 | + "\ |
| 33 | + {indent}impl Op {{\n\ |
| 34 | + {indent} /// Returns a shared reference to the result [`Slot`] of `self` if any.\n\ |
| 35 | + {indent} pub fn result_ref(&self) -> Option<&Slot> {{\n\ |
| 36 | + {indent} let res = match self {{\n\ |
| 37 | + {variants} => result,\n\ |
| 38 | + {indent} _ => return None,\n\ |
| 39 | + {indent} }};\n\ |
| 40 | + {indent} Some(res)\n\ |
| 41 | + {indent} }}\n\ |
| 42 | + \n\ |
| 43 | + {indent} /// Returns an exclusive reference to the result [`Slot`] of `self` if any.\n\ |
| 44 | + {indent} pub fn result_mut(&mut self) -> Option<&mut Slot> {{\n\ |
| 45 | + {indent} let res = match self {{\n\ |
| 46 | + {variants} => result,\n\ |
| 47 | + {indent} _ => return None,\n\ |
| 48 | + {indent} }};\n\ |
| 49 | + {indent} Some(res)\n\ |
| 50 | + {indent} }}\n\ |
| 51 | + {indent}}}\n\ |
| 52 | + " |
| 53 | + ) |
| 54 | + } |
| 55 | +} |
| 56 | + |
| 57 | +impl Display for DisplayResultMut<&'_ Op> { |
| 58 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 59 | + let indent = self.indent; |
| 60 | + let ident = DisplayIdent::camel(self.value); |
| 61 | + write!(f, "{indent}| Self::{ident} {{ result, .. }}") |
| 62 | + } |
| 63 | +} |
| 64 | + |
| 65 | +impl Op { |
| 66 | + /// Returns `true` if `self` has a result field. |
| 67 | + pub fn has_result(&self) -> bool { |
| 68 | + match self { |
| 69 | + Op::Unary(_) => true, |
| 70 | + Op::Binary(_) => true, |
| 71 | + Op::Ternary(_) => true, |
| 72 | + Op::CmpBranch(_) => false, |
| 73 | + Op::CmpSelect(_) => true, |
| 74 | + Op::Load(_) => true, |
| 75 | + Op::Store(_) => false, |
| 76 | + Op::TableGet(_) => true, |
| 77 | + Op::TableSet(_) => false, |
| 78 | + Op::Generic0(op) => op.has_result(), |
| 79 | + Op::Generic1(op) => op.has_result(), |
| 80 | + Op::Generic2(op) => op.has_result(), |
| 81 | + Op::Generic3(op) => op.has_result(), |
| 82 | + Op::Generic4(op) => op.has_result(), |
| 83 | + Op::Generic5(op) => op.has_result(), |
| 84 | + Op::V128ReplaceLane(_) => true, |
| 85 | + Op::V128LoadLane(_) => true, |
| 86 | + } |
| 87 | + } |
| 88 | +} |
0 commit comments