diff --git a/src/host/encode.rs b/src/host/encode.rs index 31bd7717..54882f7e 100644 --- a/src/host/encode.rs +++ b/src/host/encode.rs @@ -16,17 +16,17 @@ impl Host { /// Encode `tree` directly into `trg`, skipping the intermediate `Def` /// representation. pub fn encode_tree(&self, net: &mut run::Net, trg: run::Trg, tree: &Tree) { - let mut state = State { host: self, encoder: net, scope: Default::default() }; - state.visit_tree(tree, trg); - state.finish(); + // let mut state = State { host: self, encoder: net, scope: + // Default::default() }; state.visit_tree(tree, trg); + // state.finish(); } /// Encode the root of `ast_net` directly into `trg` and encode its redexes /// into `net` redex list. pub fn encode_net(&self, net: &mut run::Net, trg: run::Trg, ast_net: &Net) { - let mut state = State { host: self, encoder: net, scope: Default::default() }; - state.visit_net(ast_net, trg); - state.finish(); + // let mut state = State { host: self, encoder: net, scope: + // Default::default() }; state.visit_net(ast_net, trg); + // state.finish(); } } @@ -185,6 +185,7 @@ impl Encoder for InterpretedDef { } } +#[cfg(todo)] impl<'a, M: Mode> Encoder for run::Net<'a, M> { type Trg = run::Trg; fn link_const(&mut self, trg: Self::Trg, port: Port) { diff --git a/src/host/readback.rs b/src/host/readback.rs index 9d755b4b..3814988f 100644 --- a/src/host/readback.rs +++ b/src/host/readback.rs @@ -63,6 +63,7 @@ impl<'a> ReadbackState<'a> { let node = port.traverse_node(); Tree::Op { op, rhs: Box::new(self.read_wire(node.p1)), out: Box::new(self.read_wire(node.p2)) } } + #[cfg(todo)] Tag::Ctr => { let node = port.traverse_node(); Tree::Ctr { lab: node.lab, ports: vec![self.read_wire(node.p1), self.read_wire(node.p2)] } @@ -73,6 +74,7 @@ impl<'a> ReadbackState<'a> { let out = self.read_wire(node.p2); Tree::legacy_mat(arms, out).expect("invalid mat node") } + _ => todo!(), }) } } diff --git a/src/run/def.rs b/src/run/def.rs index cf9d8473..0368b763 100644 --- a/src/run/def.rs +++ b/src/run/def.rs @@ -239,6 +239,8 @@ impl AsDef for InterpretedDef { trgs.set_trg(TrgId::new(0), Trg::port(trg)); for i in instructions { unsafe { + todo!(); + #[cfg(todo)] match *i { Instruction::Const { trg, ref port } => trgs.set_trg(trg, Trg::port(port.clone())), Instruction::Link { a, b } => net.link_trg(trgs.get_trg(a), trgs.get_trg(b)), diff --git a/src/run/instruction.rs b/src/run/instruction.rs index fc0aa7a0..2c9c6858 100644 --- a/src/run/instruction.rs +++ b/src/run/instruction.rs @@ -111,6 +111,7 @@ impl fmt::Debug for TrgId { } } +#[cfg(todo)] impl<'a, M: Mode> Net<'a, M> { /// `trg ~ {#lab x y}` #[inline(always)] diff --git a/src/run/interact.rs b/src/run/interact.rs index 1590bddd..7125b59b 100644 --- a/src/run/interact.rs +++ b/src/run/interact.rs @@ -1,3 +1,5 @@ +use std::mem::MaybeUninit; + use super::*; impl<'a, M: Mode> Net<'a, M> { @@ -10,41 +12,32 @@ impl<'a, M: Mode> Net<'a, M> { match (a.tag(), b.tag()) { // not actually an active pair (Var | Red, _) | (_, Var | Red) => unreachable!(), - // nil-nil - (Ref, Ref | Num) if !a.is_skippable() => self.call(a, b), - (Ref | Num, Ref) if !b.is_skippable() => self.call(b, a), + + (Ref, _) if a != Port::ERA => self.call(a, b), + (_, Ref) if b != Port::ERA => self.call(b, a), + (Num | Ref | AdtZ, Num | Ref | AdtZ) => self.rwts.eras += 1, - // comm 2/2 - (Mat | Op, CtrN!() | AdtN!()) => self.comm2N(a, b), - (CtrN!() | AdtN!(), Mat | Op) => self.comm2N(b, a), - // anni - (CtrN!(), CtrN!()) => self.anniNM(a, b), - (Mat, Mat) | (Op, Op) => self.anni2(a, b), - // comm 2/0 - (Ref, CtrN!() | AdtN!()) if b.lab() >= a.lab() => self.comm0N(a, b), - (CtrN!() | AdtN!(), Ref) if a.lab() >= b.lab() => self.comm0N(b, a), - (Num, CtrN!() | AdtN!()) => self.comm0N(a, b), - (CtrN!() | AdtN!(), Num) => self.comm0N(b, a), - (AdtZ, Op | Mat) => self.comm02(a, b), - (Op | Mat, AdtZ) => self.comm02(a, b), - // TODO - (AdtN!() | AdtZ, CtrN!()) => self.adt_ctr(a, b), - (CtrN!(), AdtN!() | AdtZ) => self.adt_ctr(b, a), - (AdtN!() | AdtZ, AdtN!() | AdtZ) => todo!(), - // deref - (Ref, Mat | Op) if a == Port::ERA => self.comm02(a, b), - (Mat | Op, Ref) if b == Port::ERA => self.comm02(b, a), - (Ref, CtrN!() | AdtN!()) if a == Port::ERA => self.comm0N(a, b), - (CtrN!() | AdtN!(), Ref) if b == Port::ERA => self.comm0N(b, a), - (Ref, CtrN!() | AdtN!() | Mat | Op) => self.call(a, b), - (CtrN!() | AdtN!() | Mat | Op, Ref) => self.call(b, a), - // native ops - (Op, Num) => self.opr_num(a, b), - (Num, Op) => self.opr_num(b, a), + + (CtrN!(), CtrN!()) if a.lab() == b.lab() => self.anni(a, b), + + (AdtN!() | AdtZ, CtrN!()) if a.lab() == b.lab() => self.adt_ctr(a, b), + (CtrN!(), AdtN!() | AdtZ) if a.lab() == b.lab() => self.adt_ctr(b, a), + (AdtN!() | AdtZ, AdtN!() | AdtZ) if a.lab() == b.lab() => todo!(), + + (Mat, Mat) | (Op, Op) => self.anni(a, b), + + (CtrN!(), Mat) if a.lab() == 0 => todo!(), + (Mat, CtrN!()) if b.lab() == 0 => todo!(), + (Op, Op) if a.op() != b.op() => todo!(), + + (CtrN!(), CtrN!()) | (Op, Op) => self.anni(a, b), + + (Op, Num) => self.op_num(a, b), + (Num, Op) => self.op_num(b, a), (Mat, Num) => self.mat_num(a, b), (Num, Mat) => self.mat_num(b, a), - // todo: what should the semantics of these be? - (Op, Mat) | (Mat, Op) => unimplemented!("{:?}-{:?}", a.tag(), b.tag()), + + (_, _) => self.comm(a, b), } } @@ -209,26 +202,27 @@ impl<'a, M: Mode> Net<'a, M> { /// ``` #[inline(never)] pub fn mat_num(&mut self, a: Port, b: Port) { - trace!(self, a, b); - self.rwts.oper += 1; - let a = a.consume_node(); - let b = b.num(); - if b == 0 { - let x = self.create_node(Ctr, 0); - trace!(self, x.p0); - self.link_port_port(x.p2, Port::ERA); - self.link_wire_port(a.p2, x.p1); - self.link_wire_port(a.p1, x.p0); - } else { - let x = self.create_node(Tag::Ctr, 0); - let y = self.create_node(Tag::Ctr, 0); - trace!(self, x.p0, y.p0); - self.link_port_port(x.p1, Port::ERA); - self.link_port_port(x.p2, y.p0); - self.link_port_port(y.p1, Port::new_num(b - 1)); - self.link_wire_port(a.p2, y.p2); - self.link_wire_port(a.p1, x.p0); - } + todo!() + // trace!(self, a, b); + // self.rwts.oper += 1; + // let a = a.consume_node(); + // let b = b.num(); + // if b == 0 { + // let x = self.create_node(Ctr, 0); + // trace!(self, x.p0); + // self.link_port_port(x.p2, Port::ERA); + // self.link_wire_port(a.p2, x.p1); + // self.link_wire_port(a.p1, x.p0); + // } else { + // let x = self.create_node(Tag::Ctr, 0); + // let y = self.create_node(Tag::Ctr, 0); + // trace!(self, x.p0, y.p0); + // self.link_port_port(x.p1, Port::ERA); + // self.link_port_port(x.p2, y.p0); + // self.link_port_port(y.p1, Port::new_num(b - 1)); + // self.link_wire_port(a.p2, y.p2); + // self.link_wire_port(a.p1, x.p0); + // } } /// Interacts a number and a binary numeric operation node. @@ -276,19 +270,56 @@ impl<'a, M: Mode> Net<'a, M> { } } - fn comm2N(&mut self, a: Port, b: Port) { - todo!() - } - - fn anniNM(&mut self, a: Port, b: Port) { + fn adt_ctr(&mut self, adt: Port, ctr: Port) { + let ctr_arity = ctr.tag().arity(); todo!() } - fn comm0N(&mut self, a: Port, b: Port) { + fn anni(&self, a: Port, b: Port) { todo!() } - fn adt_ctr(&mut self, b: Port, a: Port) { - todo!() + fn comm(&mut self, a: Port, b: Port) { + let mut Bs = [const { MaybeUninit::::uninit() }; 8]; + let mut As = [const { MaybeUninit::::uninit() }; 8]; + let aa = a.tag().arity(); + // let aw = b.tag().width(); + let ba = b.tag().arity(); + // let bw = b.tag().width(); + let Bs = &mut Bs[0 .. aa as usize]; + let As = &mut As[0 .. ba as usize]; + if ba != 0 { + for B in &mut *Bs { + let addr = self.alloc(b.align()); + *B = MaybeUninit::new(b.with_addr(addr)); + } + } + if aa != 0 { + for A in &mut *As { + let addr = self.alloc(a.align()); + *A = MaybeUninit::new(a.with_addr(addr)); + } + } + for bi in 0 .. aa { + for ai in 0 .. ba { + unsafe { + self.link_port_port( + As.get_unchecked(ai as usize).assume_init_ref().aux_port(bi), + Bs.get_unchecked(bi as usize).assume_init_ref().aux_port(ai), + ); + } + } + } + // TODO: copy width - arity + for i in 0 .. aa { + unsafe { + self.link_wire_port(a.aux_port(i).wire(), Bs.get_unchecked(i as usize).assume_init_read()); + } + } + for i in 0 .. ba { + unsafe { + self.link_wire_port(b.aux_port(i).wire(), As.get_unchecked(i as usize).assume_init_read()); + } + } } } diff --git a/src/run/net.rs b/src/run/net.rs index d0317064..c0deb9e2 100644 --- a/src/run/net.rs +++ b/src/run/net.rs @@ -159,6 +159,8 @@ impl AsDef for ExpandDef { unreachable!() } Tag::Ref | Tag::Num | Tag::Var => net.link_port_port(def.data.out, port), + _ => todo!(), + #[cfg(todo)] tag @ (Tag::Op | Tag::Mat | Tag::Ctr) => { let old = port.consume_node(); let new = net.create_node(tag, old.lab); diff --git a/src/run/port.rs b/src/run/port.rs index b3519d76..b0ac76a5 100644 --- a/src/run/port.rs +++ b/src/run/port.rs @@ -195,4 +195,12 @@ impl Port { pub(super) fn is_ctr_ish(&self) -> bool { (self.0 & 0b111) > 0b100 } + + pub(super) fn aux_port(&self, i: u8) -> Port { + todo!() + } + + pub(super) fn with_addr(&self, addr: Addr) -> Port { + todo!() + } } diff --git a/src/run/tag.rs b/src/run/tag.rs index d5304d99..12c9e6d2 100644 --- a/src/run/tag.rs +++ b/src/run/tag.rs @@ -56,7 +56,8 @@ impl Tag { match self { Tag::Num | Tag::Ref | Tag::AdtZ => 0, Tag::Red | Tag::Var => 1, - Tag::Op | Tag::Mat => 2, + Tag::Op => 2, + Tag::Mat => 3, CtrN!() | AdtN!() => (1 << (self.align() as u8 - 1)) + 1 + (self as u8 >> 4), } } @@ -70,6 +71,14 @@ impl Tag { _ => self.width(), } } + + pub(super) fn ctr_with_arity(arity: u8) -> Tag { + let sub = arity - 1; + let ilog = unsafe { sub.checked_ilog2().unwrap_unchecked() as u8 }; + let ext = sub - (1 << ilog); + let tag = (ilog + 1) | 0b100 | (ext << 4); + unsafe { Tag::from_unchecked(tag) } + } } /// Matches any `Ctr` tag. @@ -132,4 +141,7 @@ fn test_tag_width() { use Tag::*; assert_eq!([Ctr2, Ctr3, Ctr4, Ctr5, Ctr6, Ctr7, Ctr8].map(Tag::width), [2, 3, 4, 5, 6, 7, 8]); assert_eq!([Adt2, Adt3, Adt4, Adt5, Adt6, Adt7, Adt8].map(Tag::width), [2, 3, 4, 5, 6, 7, 8]); + for t in [Ctr2, Ctr3, Ctr4, Ctr5, Ctr6, Ctr7, Ctr8] { + assert_eq!(Tag::ctr_with_arity(t.width()), t); + } } diff --git a/src/stdlib.rs b/src/stdlib.rs index 995c2f57..cd83932f 100644 --- a/src/stdlib.rs +++ b/src/stdlib.rs @@ -10,8 +10,12 @@ use crate::{ pub const IDENTITY: *const Def = const { &Def::new(LabSet::from_bits(&[1]), (call_identity, call_identity)) }.upcast(); fn call_identity(net: &mut Net, port: Port) { - let (a, b) = net.do_ctr(0, Trg::port(port)); - net.link_trg(a, b); + #[cfg(todo)] + { + let (a, b) = net.do_ctr(0, Trg::port(port)); + net.link_trg(a, b); + } + todo!() } /// The definition of `HVM.log`, parameterized by the readback function. @@ -25,10 +29,13 @@ pub struct LogDef(F); impl LogDef { pub fn new(f: F) -> Def { - Def::new(LabSet::ALL, LogDef(f)) + #[cfg(todo)] + Def::new(LabSet::ALL, LogDef(f)); + todo!() } } +#[cfg(todo)] impl AsDef for LogDef { unsafe fn call(def: *const Def, net: &mut Net, port: Port) { let def = unsafe { &*def }; @@ -91,6 +98,8 @@ impl AsDef for ActiveLogDef { } } Tag::Ref | Tag::Num | Tag::Var => net.link_port_port(def.data.out, port), + _ => todo!(), + #[cfg(todo)] tag @ (Tag::Op | Tag::Mat | Tag::Ctr) => { let old = port.consume_node(); let new = net.create_node(tag, old.lab);