diff --git a/src/sea_of_nodes/nodes.rs b/src/sea_of_nodes/nodes.rs index 16cfb39..d54a964 100644 --- a/src/sea_of_nodes/nodes.rs +++ b/src/sea_of_nodes/nodes.rs @@ -292,7 +292,7 @@ impl Node { pub fn err(self, sea: &Nodes) -> Option { if let Some(memop) = self.to_mem_name(sea) { let ptr = self.inputs(sea)[2]?.ty(sea)?; - if ptr == sea.types.ty_bot || matches!(*ptr, Type::Pointer(MemPtr { nil: true, .. })) { + if ptr == sea.types.bot || matches!(*ptr, Type::Pointer(MemPtr { nil: true, .. })) { return Some(format!("Might be null accessing '{memop}'")); } } @@ -360,8 +360,7 @@ impl Node { impl Phi { fn single_unique_input(self, sea: &mut Nodes) -> Option { let region = self.inputs(sea)[0].unwrap(); - if region.is_loop(sea) && region.inputs(sea)[1].unwrap().ty(sea) == Some(sea.types.ty_xctrl) - { + if region.is_loop(sea) && region.inputs(sea)[1].unwrap().ty(sea) == Some(sea.types.xctrl) { return None; // Dead entry loops just ignore and let the loop collapse } @@ -370,8 +369,7 @@ impl Phi { // If the region's control input is live, add this as a dependency // to the control because we can be peeped should it become dead. let region_in_i = region.inputs(sea)[i].unwrap().add_dep(*self, sea); - if region_in_i.ty(sea) != Some(sea.types.ty_xctrl) && self.inputs(sea)[i] != Some(*self) - { + if region_in_i.ty(sea) != Some(sea.types.xctrl) && self.inputs(sea)[i] != Some(*self) { if live.is_none() || live == self.inputs(sea)[i] { live = self.inputs(sea)[i]; } else { diff --git a/src/sea_of_nodes/nodes/idealize.rs b/src/sea_of_nodes/nodes/idealize.rs index 1259cb1..9223696 100644 --- a/src/sea_of_nodes/nodes/idealize.rs +++ b/src/sea_of_nodes/nodes/idealize.rs @@ -45,13 +45,13 @@ impl Add { // Add of 0. We do not check for (0+x) because this will already // canonicalize to (x+0) - if t2 == sea.types.ty_int_zero { + if t2 == sea.types.int_zero { return Some(lhs); } // Add of same to a multiply by 2 if lhs == rhs { - let two = Constant::new(sea.types.ty_int_two, sea).peephole(sea); + let two = Constant::new(sea.types.int_two, sea).peephole(sea); return Some(*Mul::new(lhs, two, sea)); } @@ -195,9 +195,9 @@ impl Bool { let op = sea[self]; if self.inputs(sea)[1]? == self.inputs(sea)[2]? { let value = if op.compute(3, 3) { - sea.types.ty_int_one + sea.types.int_one } else { - sea.types.ty_int_zero + sea.types.int_zero }; return Some(*Constant::new(value, sea)); } @@ -217,8 +217,8 @@ impl Bool { } } // Equals X==0 becomes a !X - if rhs.ty(sea) == Some(sea.types.ty_int_zero) - || rhs.ty(sea) == Some(sea.types.ty_pointer_null) + if rhs.ty(sea) == Some(sea.types.int_zero) + || rhs.ty(sea) == Some(sea.types.pointer_null) { return Some(*Not::new(lhs, sea)); } @@ -338,7 +338,7 @@ impl Stop { let mut result = None; let mut i = 0; while i < self.inputs(sea).len() { - if self.inputs(sea)[i].unwrap().ty(sea) == Some(sea.types.ty_xctrl) { + if self.inputs(sea)[i].unwrap().ty(sea) == Some(sea.types.xctrl) { self.del_def(i, sea); result = Some(*self); } else { @@ -351,7 +351,7 @@ impl Stop { impl Return { fn idealize_return(self, sea: &mut Nodes) -> Option { - self.inputs(sea)[0].filter(|ctrl| ctrl.ty(sea) == Some(sea.types.ty_xctrl)) + self.inputs(sea)[0].filter(|ctrl| ctrl.ty(sea) == Some(sea.types.xctrl)) } } @@ -360,7 +360,7 @@ impl CProj { let index = sea[self].index; if let Some(iff) = self.inputs(sea)[0]?.to_if(sea) { if let Some(Type::Tuple { types: ts }) = iff.ty(sea).as_deref() { - if ts[1 - index] == sea.types.ty_xctrl { + if ts[1 - index] == sea.types.xctrl { return iff.inputs(sea)[0]; // We become our input control } } @@ -476,9 +476,9 @@ impl If { if d.pred(sea).unwrap().add_dep(*self, sea) == pred { if let Op::CProj(p) = &sea[prior] { let value = if p.index == 0 { - sea.types.ty_int_one + sea.types.int_one } else { - sea.types.ty_int_zero + sea.types.int_zero }; let new_constant = Constant::new(value, sea).peephole(sea); self.set_def(1, Some(new_constant), sea); @@ -521,8 +521,7 @@ impl Load { // else ptr.x = e1; : e1; // val = ptr.x; ptr.x = val; if let Some(mem) = mem.to_phi(sea) { - if mem.inputs(sea)[0]?.ty(sea) == Some(sea.types.ty_ctrl) && mem.inputs(sea).len() == 3 - { + if mem.inputs(sea)[0]?.ty(sea) == Some(sea.types.ctrl) && mem.inputs(sea).len() == 3 { // Profit on RHS/Loop backedge if self.profit(mem, 2, sea) || // Else must not be a loop to count profit on LHS. @@ -643,7 +642,7 @@ impl Div { impl Node { fn find_dead_input(self, sea: &Nodes) -> Option { (1..self.inputs(sea).len()) - .find(|&i| self.inputs(sea)[i].unwrap().ty(sea).unwrap() == sea.types.ty_xctrl) + .find(|&i| self.inputs(sea)[i].unwrap().ty(sea).unwrap() == sea.types.xctrl) } } @@ -662,12 +661,12 @@ impl<'t> Nodes<'t> { } if matches!(self[lo], Op::Phi(_)) - && self.ty[self.inputs[lo][0].unwrap()] == Some(self.types.ty_xctrl) + && self.ty[self.inputs[lo][0].unwrap()] == Some(self.types.xctrl) { return false; } if matches!(self[hi], Op::Phi(_)) - && self.ty[self.inputs[hi][0].unwrap()] == Some(self.types.ty_xctrl) + && self.ty[self.inputs[hi][0].unwrap()] == Some(self.types.xctrl) { return false; } diff --git a/src/sea_of_nodes/nodes/peephole.rs b/src/sea_of_nodes/nodes/peephole.rs index 4c9f973..2cbfc2f 100644 --- a/src/sea_of_nodes/nodes/peephole.rs +++ b/src/sea_of_nodes/nodes/peephole.rs @@ -49,7 +49,7 @@ impl<'t> Node { // Replace constant computations from non-constants with a constant node if !self.is_constant(sea) && !self.is_xctrl(sea) && ty.is_high_or_constant() { - return if ty == sea.types.ty_xctrl { + return if ty == sea.types.xctrl { *XCtrl::new(sea) } else { *Constant::new(ty, sea) @@ -112,14 +112,14 @@ impl<'t> Node { let types = sea.types; match &sea[self] { Op::Constant(ty) => *ty, - Op::XCtrl => types.ty_xctrl, + Op::XCtrl => types.xctrl, Op::Return => { let ctrl = self.inputs(sea)[0] .and_then(|n| n.ty(sea)) - .unwrap_or(types.ty_bot); + .unwrap_or(types.bot); let expr = self.inputs(sea)[1] .and_then(|n| n.ty(sea)) - .unwrap_or(types.ty_bot); + .unwrap_or(types.bot); types.get_tuple_from_array([ctrl, expr]) } Op::Start(s) => s.args, @@ -127,7 +127,7 @@ impl<'t> Node { Op::Sub => { // Sub of same is 0 if self.inputs(sea)[1] == self.inputs(sea)[2] { - sea.types.ty_int_zero + sea.types.int_zero } else { self.compute_binary_int(i64::wrapping_sub, sea) } @@ -138,82 +138,82 @@ impl<'t> Node { } Op::Minus => { let Some(input) = self.inputs(sea)[1].and_then(|n| n.ty(sea)) else { - return types.ty_bot; + return types.bot; }; match &*input { Type::Int(Int::Constant(v)) => types.get_int(v.wrapping_neg()), - _ => types.meet(types.ty_top, input), + _ => types.meet(types.top, input), } } - Op::Scope(_) => types.ty_bot, + Op::Scope(_) => types.bot, Op::Bool(op) => self.compute_binary_int(|x, y| op.compute(x, y) as i64, sea), Op::Not => { let t0 = self.inputs(sea)[1].unwrap().ty(sea).unwrap(); match &*t0 { Type::Int(i) => match i { - Int::Constant(0) => types.ty_int_one, - Int::Constant(_) => types.ty_int_zero, + Int::Constant(0) => types.int_one, + Int::Constant(_) => types.int_zero, _ => t0, }, Type::Pointer(p) => { // top->top, bot->bot, null->1, *void->0, not-null ptr->0, ptr/nil->bot // If input in null then true // If input is not null ptr then false - if t0 == types.ty_pointer_top { - types.ty_int_top - } else if t0 == types.ty_pointer_null { - types.ty_int_one + if t0 == types.pointer_top { + types.int_top + } else if t0 == types.pointer_null { + types.int_one } else if !p.nil { - types.ty_int_zero + types.int_zero } else { - types.ty_int_bot + types.int_bot } } _ => { // Only doing NOT on ints and ptrs - assert!(t0 == types.ty_top || t0 == types.ty_bot); - if t0 == types.ty_top { + assert!(t0 == types.top || t0 == types.bot); + if t0 == types.top { t0 } else { - types.ty_bot + types.bot } } } } Op::Proj(n) | Op::CProj(n) => { let Some(input) = self.inputs(sea)[0].and_then(|n| n.ty(sea)) else { - return types.ty_bot; + return types.bot; }; match &*input { Type::Tuple { types } => types[n.index], _ => unreachable!("proj node ctrl must always be tuple, if present"), } } - Op::If(IfOp::Never) => types.ty_int_bot, + Op::If(IfOp::Never) => types.int_bot, Op::If(IfOp::Cond) => { let s = self.to_if(sea).unwrap(); // If the If node is not reachable then neither is any following Proj let ctrl_ty = self.inputs(sea)[0].unwrap().ty(sea); - if ctrl_ty != Some(types.ty_ctrl) && ctrl_ty != Some(types.ty_bot) { - return types.ty_if_neither; + if ctrl_ty != Some(types.ctrl) && ctrl_ty != Some(types.bot) { + return types.if_neither; } let t = s.pred(sea).unwrap().ty(sea).unwrap(); // High types mean NEITHER side is reachable. // Wait until the type falls to decide which way to go. - if t == types.ty_top || t == types.ty_int_top { - return types.ty_if_neither; + if t == types.top || t == types.int_top { + return types.if_neither; } // If constant is 0 then false branch is reachable // Else true branch is reachable if let Type::Int(Int::Constant(c)) = &*t { return if *c == 0 { - types.ty_if_false + types.if_false } else { - types.ty_if_true + types.if_true }; } @@ -228,9 +228,9 @@ impl<'t> Node { return if let Op::Proj(proj) = &sea[prior] { // Repeated test, dominated on one side. Test result is the same. if proj.index == 0 { - types.ty_if_true + types.if_true } else { - types.ty_if_false + types.if_false } } else { // Repeated test not dominated on one side @@ -243,13 +243,13 @@ impl<'t> Node { dom = d.idom(sea); } - types.ty_if_both + types.if_both } Op::Phi(_) => { let region = self.inputs(sea)[0].unwrap(); if !sea.instanceof_region(Some(region)) { - if region.ty(sea) == Some(types.ty_xctrl) { - types.ty_top + if region.ty(sea) == Some(types.xctrl) { + types.top } else { self.ty(sea).unwrap() } @@ -266,7 +266,7 @@ impl<'t> Node { // If the region's control input is live, add this as a dependency // to the control because we can be peeped should it become dead. if region.inputs(sea)[i].unwrap().add_dep(self, sea).ty(sea) - != Some(types.ty_xctrl) + != Some(types.xctrl) { t = types.meet(t, self.inputs(sea)[i].unwrap().ty(sea).unwrap()) } @@ -276,24 +276,21 @@ impl<'t> Node { } Op::Region { .. } => { if Nodes::in_progress(&sea.ops, &sea.inputs, self) { - types.ty_ctrl + types.ctrl } else { - self.inputs(sea) - .iter() - .skip(1) - .fold(types.ty_xctrl, |t, n| { - types.meet(t, n.unwrap().ty(sea).unwrap()) - }) + self.inputs(sea).iter().skip(1).fold(types.xctrl, |t, n| { + types.meet(t, n.unwrap().ty(sea).unwrap()) + }) } } Op::Loop => { if Nodes::in_progress(&sea.ops, &sea.inputs, self) { - types.ty_ctrl + types.ctrl } else { self.inputs(sea)[1].unwrap().ty(sea).unwrap() } } - Op::Stop => types.ty_bot, + Op::Stop => types.bot, Op::Cast(t) => types.join(self.inputs(sea)[1].unwrap().ty(sea).unwrap(), *t), Op::Load(l) => l.declared_type, Op::Store(s) => types.get_mem(s.alias), @@ -304,10 +301,10 @@ impl<'t> Node { fn compute_binary_int i64>(self, op: F, sea: &Nodes<'t>) -> Ty<'t> { let types = sea.types; let Some(first) = self.inputs(sea)[1].and_then(|n| n.ty(sea)) else { - return types.ty_bot; + return types.bot; }; let Some(second) = self.inputs(sea)[2].and_then(|n| n.ty(sea)) else { - return types.ty_bot; + return types.bot; }; match [&*first, &*second] { diff --git a/src/sea_of_nodes/nodes/scope.rs b/src/sea_of_nodes/nodes/scope.rs index 68b9dd9..707ded0 100644 --- a/src/sea_of_nodes/nodes/scope.rs +++ b/src/sea_of_nodes/nodes/scope.rs @@ -242,7 +242,7 @@ impl<'t> Scope { invert: bool, sea: &mut Nodes<'t>, ) -> Option { - if ctrl.ty(sea)? == sea.types.ty_xctrl { + if ctrl.ty(sea)? == sea.types.xctrl { return None; } // Invert the If conditional @@ -263,11 +263,11 @@ impl<'t> Scope { // being tested. No representation for a generic not-null int, so no upcast. return None; }; - if sea.types.isa(tmp, sea.types.ty_pointer_void) { + if sea.types.isa(tmp, sea.types.pointer_void) { return None; // Already not-null, no reason to upcast } // Upcast the ptr to not-null ptr, and replace in scope - let c = Cast::new(sea.types.ty_pointer_void, ctrl, pred, sea).peephole(sea); + let c = Cast::new(sea.types.pointer_void, ctrl, pred, sea).peephole(sea); let t = c.compute(sea); c.set_type(t, sea); self.replace(pred, Some(c), sea); diff --git a/src/sea_of_nodes/parser.rs b/src/sea_of_nodes/parser.rs index 42eae0c..10bcf88 100644 --- a/src/sea_of_nodes/parser.rs +++ b/src/sea_of_nodes/parser.rs @@ -59,20 +59,20 @@ pub fn is_keyword(s: &str) -> bool { impl<'s, 't> Parser<'s, 't> { pub fn new(source: &'s str, types: &'t Types<'t>) -> Self { - Self::new_with_arg(source, types, types.ty_int_bot) + Self::new_with_arg(source, types, types.int_bot) } pub fn new_with_arg(source: &'s str, types: &'t Types<'t>, arg: Ty<'t>) -> Self { let mut nodes = Nodes::new(types); let scope = Scope::new(&mut nodes); - nodes.ty[scope] = Some(types.ty_bot); // in java this is done by the constructor + nodes.ty[scope] = Some(types.bot); // in java this is done by the constructor - nodes.start = Start::new(&[types.ty_ctrl, arg], &mut nodes); + nodes.start = Start::new(&[types.ctrl, arg], &mut nodes); let stop = Stop::new(&mut nodes); - nodes.zero = Constant::new(types.ty_int_zero, &mut nodes) + nodes.zero = Constant::new(types.int_zero, &mut nodes) .peephole(&mut nodes) .keep(&mut nodes) .to_constant(&nodes) @@ -117,18 +117,18 @@ impl<'s, 't> Parser<'s, 't> { let start = self.nodes.start; let ctrl = CProj::new(start, 0, Scope::CTRL, &mut self.nodes).peephole(&mut self.nodes); self.scope - .define(Scope::CTRL, self.types.ty_ctrl, ctrl, &mut self.nodes) + .define(Scope::CTRL, self.types.ctrl, ctrl, &mut self.nodes) .expect("not in scope"); let arg0 = Proj::new(start, 1, Scope::ARG0, &mut self.nodes).peephole(&mut self.nodes); self.scope - .define(Scope::ARG0, self.types.ty_int_bot, arg0, &mut self.nodes) + .define(Scope::ARG0, self.types.int_bot, arg0, &mut self.nodes) .expect("not in scope"); self.parse_block()?; - if self.ctrl().ty(&self.nodes) == Some(self.types.ty_ctrl) { + if self.ctrl().ty(&self.nodes) == Some(self.types.ctrl) { let ctrl = self.ctrl(); let expr = - Constant::new(self.types.ty_int_zero, &mut self.nodes).peephole(&mut self.nodes); + Constant::new(self.types.int_zero, &mut self.nodes).peephole(&mut self.nodes); let ret = Return::new(ctrl, expr, Some(self.scope), &mut self.nodes) .peephole(&mut self.nodes); self.stop.add_def(Some(ret), &mut self.nodes); @@ -178,7 +178,7 @@ impl<'s, 't> Parser<'s, 't> { if self.matchx("return") { self.parse_return() } else if self.matchx("int") { - self.parse_decl(self.types.ty_int_bot) + self.parse_decl(self.types.int_bot) } else if self.match_("{") { self.parse_block()?; self.require("}") @@ -212,7 +212,7 @@ impl<'s, 't> Parser<'s, 't> { if self.matchx("int") { let name = self.types.get_str(self.require_id()?); self.require(";")?; - return Ok((name, self.types.ty_int_bot)); + return Ok((name, self.types.int_bot)); } Err("A field type is expected, only type 'int' is supported at present".to_string()) } @@ -561,7 +561,7 @@ impl<'s, 't> Parser<'s, 't> { let old = self.lexer.remaining; let tname = self.lexer.match_id()?; if tname == "int" { - Some(self.types.ty_int_bot) + Some(self.types.int_bot) } else if let Some(&obj) = self.name_to_type.get(tname) { let nil = self.match_("?"); Some(self.types.get_pointer(obj, nil)) @@ -717,14 +717,11 @@ impl<'s, 't> Parser<'s, 't> { self.require(")")?; Ok(e) } else if self.matchx("true") { - Ok(Constant::new(self.types.ty_int_one, &mut self.nodes).peephole(&mut self.nodes)) + Ok(Constant::new(self.types.int_one, &mut self.nodes).peephole(&mut self.nodes)) } else if self.matchx("false") { Ok(*self.nodes.zero) } else if self.matchx("null") { - Ok( - Constant::new(self.types.ty_pointer_null, &mut self.nodes) - .peephole(&mut self.nodes), - ) + Ok(Constant::new(self.types.pointer_null, &mut self.nodes).peephole(&mut self.nodes)) } else if self.matchx("new") { let ty_name = self.require_id()?; let ty = self.name_to_type.get(ty_name); diff --git a/src/sea_of_nodes/tests/chapter05.rs b/src/sea_of_nodes/tests/chapter05.rs index 4bf6842..0d00f23 100644 --- a/src/sea_of_nodes/tests/chapter05.rs +++ b/src/sea_of_nodes/tests/chapter05.rs @@ -41,7 +41,7 @@ if (arg == 1) { } return c;", &types, - types.ty_int_bot, + types.int_bot, ); let stop = parser.parse().unwrap(); parser.iterate(stop); @@ -62,7 +62,7 @@ else return 4; ", &types, - types.ty_int_bot, + types.int_bot, ); let stop = parser.parse().unwrap(); assert_eq!(parser.print(stop), "Stop[ return 3; return 4; ]"); @@ -134,7 +134,7 @@ else return a; ", &types, - types.ty_int_bot, + types.int_bot, ); let stop = parser.parse().unwrap(); parser.iterate(stop); @@ -161,7 +161,7 @@ if( arg==0 ) return arg+a+b; ", &types, - types.ty_int_bot, + types.int_bot, ); let stop = parser.parse().unwrap(); assert_eq!( diff --git a/src/sea_of_nodes/tests/chapter06.rs b/src/sea_of_nodes/tests/chapter06.rs index d275dbc..a3e10ab 100644 --- a/src/sea_of_nodes/tests/chapter06.rs +++ b/src/sea_of_nodes/tests/chapter06.rs @@ -83,7 +83,7 @@ else b=5; return b;", &types, - types.ty_int_bot, + types.int_bot, ); let stop = parser.parse().unwrap(); parser.iterate(stop); @@ -110,7 +110,7 @@ else b=5; return b;", &types, - types.ty_int_bot, + types.int_bot, ); let stop = parser.parse().unwrap(); parser.iterate(stop); @@ -191,7 +191,7 @@ else return a; ", &types, - types.ty_int_bot, + types.int_bot, ); let stop = parser.parse().unwrap(); parser.iterate(stop); diff --git a/src/sea_of_nodes/tests/chapter09.rs b/src/sea_of_nodes/tests/chapter09.rs index 1562cce..3888ca8 100644 --- a/src/sea_of_nodes/tests/chapter09.rs +++ b/src/sea_of_nodes/tests/chapter09.rs @@ -423,13 +423,13 @@ fn test_fuzz_8() { fn test_meet() { let arena = DroplessArena::new(); let types = Types::new(&arena); - let mut t1 = types.ty_top; - let mut t2 = types.ty_int_top; - - assert_eq!(types.ty_int_top.clone(), types.meet(t1, t2)); - assert_eq!(types.ty_int_top.clone(), types.meet(t2, t1)); - t1 = types.ty_bot; - t2 = types.ty_int_bot; - assert_eq!(types.ty_bot.clone(), types.meet(t1, t2)); - assert_eq!(types.ty_bot.clone(), types.meet(t2, t1)); + let mut t1 = types.top; + let mut t2 = types.int_top; + + assert_eq!(types.int_top.clone(), types.meet(t1, t2)); + assert_eq!(types.int_top.clone(), types.meet(t2, t1)); + t1 = types.bot; + t2 = types.int_bot; + assert_eq!(types.bot.clone(), types.meet(t1, t2)); + assert_eq!(types.bot.clone(), types.meet(t2, t1)); } diff --git a/src/sea_of_nodes/tests/evaluator.rs b/src/sea_of_nodes/tests/evaluator.rs index 612f3c8..fe065f3 100644 --- a/src/sea_of_nodes/tests/evaluator.rs +++ b/src/sea_of_nodes/tests/evaluator.rs @@ -250,7 +250,7 @@ impl<'a, 't> Evaluator<'a, 't> { pub fn evaluate(&mut self, parameter: i64, mut loops: usize) -> EResult { self.values[self.start] = Object::Obj(self.heap.objs.len()); self.heap.objs.push(Obj { - ty: self.sea.types.ty_struct_bot.try_into().unwrap(), // dummy + ty: self.sea.types.struct_bot.try_into().unwrap(), // dummy fields: { let Type::Tuple { types } = &*self.sea[self.start].args else { unreachable!(); diff --git a/src/sea_of_nodes/tests/scheduler.rs b/src/sea_of_nodes/tests/scheduler.rs index a42440f..a36e091 100644 --- a/src/sea_of_nodes/tests/scheduler.rs +++ b/src/sea_of_nodes/tests/scheduler.rs @@ -145,7 +145,7 @@ impl Scheduler { fn is_not_xctrl(node: Node, sea: &Nodes) -> bool { !node .to_constant(sea) - .is_some_and(|c| sea[c] == sea.types.ty_xctrl) + .is_some_and(|c| sea[c] == sea.types.xctrl) && !node.is_xctrl(sea) } diff --git a/src/sea_of_nodes/tests/type_test.rs b/src/sea_of_nodes/tests/type_test.rs index 3b97557..5b1372b 100644 --- a/src/sea_of_nodes/tests/type_test.rs +++ b/src/sea_of_nodes/tests/type_test.rs @@ -8,8 +8,8 @@ fn test_type_ad_hoc() { let arena = DroplessArena::new(); let types = Types::new(&arena); - let s1 = types.get_struct("s1", &[("a", types.ty_int_bot), ("b", types.ty_int_bot)]); - let s2 = types.get_struct("s2", &[("a", types.ty_int_bot), ("b", types.ty_int_bot)]); + let s1 = types.get_struct("s1", &[("a", types.int_bot), ("b", types.int_bot)]); + let s2 = types.get_struct("s2", &[("a", types.int_bot), ("b", types.int_bot)]); assert_eq!(s1, types.glb(s1)); assert_ne!(s1, types.dual(s1)); assert_eq!(s1, types.glb(types.dual(s1))); @@ -23,14 +23,14 @@ fn test_type_ad_hoc() { assert_ne!(m2, m3); assert_ne!(m3, m4); - assert_eq!(types.ty_struct_bot, types.meet(s1, s2)); - assert_eq!(types.ty_memory_bot, types.meet(m1, m2)); - assert_eq!(types.ty_memory_bot, types.meet(m2, m3)); - assert_eq!(types.ty_memory_bot, types.meet(m3, m4)); + assert_eq!(types.struct_bot, types.meet(s1, s2)); + assert_eq!(types.memory_bot, types.meet(m1, m2)); + assert_eq!(types.memory_bot, types.meet(m2, m3)); + assert_eq!(types.memory_bot, types.meet(m3, m4)); - assert_eq!(types.ty_memory_bot, types.glb(m1)); + assert_eq!(types.memory_bot, types.glb(m1)); assert_eq!(m1, types.dual(m1)); - assert_eq!(types.ty_memory_top, types.dual(types.glb(m1))); + assert_eq!(types.memory_top, types.dual(types.glb(m1))); let ptr1 = types.get_pointer(s1, false); assert!(matches!(*ptr1, Type::Pointer(MemPtr {to, nil: false}) if to == s1)); @@ -48,13 +48,13 @@ fn test_type_ad_hoc() { assert_eq!(ptr1, types.dual(types.dual(ptr1))); assert_eq!(types.glb(ptr1), types.glb(types.dual(ptr1))); - assert_eq!(types.ty_pointer_bot, types.meet(ptr1, ptr2nil)); - assert_eq!(types.glb(ptr1), types.meet(ptr1, types.ty_pointer_null)); + assert_eq!(types.pointer_bot, types.meet(ptr1, ptr2nil)); + assert_eq!(types.glb(ptr1), types.meet(ptr1, types.pointer_null)); - let top = types.ty_pointer_top; - let bot = types.ty_pointer_bot; - let ptr = types.ty_pointer_void; - let null = types.ty_pointer_null; + let top = types.pointer_top; + let bot = types.pointer_bot; + let ptr = types.pointer_void; + let null = types.pointer_null; assert_eq!(bot, types.meet(ptr, null)); assert_eq!(ptr, types.meet(ptr1, ptr2)); @@ -151,26 +151,26 @@ impl<'t> Types<'t> { } fn gather(&self) -> Vec> { - let struct_test = self.get_struct("test", &[("test", self.ty_int_zero)]); + let struct_test = self.get_struct("test", &[("test", self.int_zero)]); let pointer_test = self.get_pointer(struct_test, false); let mut ts = vec![ - self.ty_bot, - self.ty_ctrl, + self.bot, + self.ctrl, // - self.ty_int_zero, - self.ty_bot, + self.int_zero, + self.bot, // self.get_mem(1), - self.ty_memory_bot, + self.memory_bot, // - self.ty_pointer_null, - self.ty_pointer_bot, + self.pointer_null, + self.pointer_bot, pointer_test, // struct_test, - self.ty_struct_bot, + self.struct_bot, // - self.get_tuple_from_array([self.ty_int_bot, pointer_test]), + self.get_tuple_from_array([self.int_bot, pointer_test]), ]; let t2 = ts.iter().map(|t| self.dual(*t)).collect::>(); ts.extend(t2); diff --git a/src/sea_of_nodes/types.rs b/src/sea_of_nodes/types.rs index a089572..f214d0a 100644 --- a/src/sea_of_nodes/types.rs +++ b/src/sea_of_nodes/types.rs @@ -34,27 +34,27 @@ mod r#type; pub struct Types<'a> { interner: Interner<'a>, - pub ty_bot: Ty<'a>, - pub ty_top: Ty<'a>, - pub ty_ctrl: Ty<'a>, - pub ty_xctrl: Ty<'a>, - pub ty_int_zero: Ty<'a>, - pub ty_int_one: Ty<'a>, - pub ty_int_two: Ty<'a>, - pub ty_int_bot: Ty<'a>, - pub ty_int_top: Ty<'a>, - pub ty_if_both: Ty<'a>, - pub ty_if_neither: Ty<'a>, - pub ty_if_true: Ty<'a>, - pub ty_if_false: Ty<'a>, - pub ty_struct_bot: Ty<'a>, - pub ty_struct_top: Ty<'a>, - pub ty_memory_bot: Ty<'a>, - pub ty_memory_top: Ty<'a>, - pub ty_pointer_top: Ty<'a>, - pub ty_pointer_bot: Ty<'a>, - pub ty_pointer_null: Ty<'a>, - pub ty_pointer_void: Ty<'a>, + pub bot: Ty<'a>, + pub top: Ty<'a>, + pub ctrl: Ty<'a>, + pub xctrl: Ty<'a>, + pub int_zero: Ty<'a>, + pub int_one: Ty<'a>, + pub int_two: Ty<'a>, + pub int_bot: Ty<'a>, + pub int_top: Ty<'a>, + pub if_both: Ty<'a>, + pub if_neither: Ty<'a>, + pub if_true: Ty<'a>, + pub if_false: Ty<'a>, + pub struct_bot: Ty<'a>, + pub struct_top: Ty<'a>, + pub memory_bot: Ty<'a>, + pub memory_top: Ty<'a>, + pub pointer_top: Ty<'a>, + pub pointer_bot: Ty<'a>, + pub pointer_null: Ty<'a>, + pub pointer_void: Ty<'a>, } impl<'a> Types<'a> { @@ -69,44 +69,44 @@ impl<'a> Types<'a> { let ty_struct_top = intern(Type::Struct(Struct::Top)); Self { - ty_bot: intern(Type::Bot), - ty_top: intern(Type::Top), - ty_ctrl, - ty_xctrl, - ty_int_zero: intern(Type::Int(Int::Constant(0))), - ty_int_one: intern(Type::Int(Int::Constant(1))), - ty_int_two: intern(Type::Int(Int::Constant(2))), - ty_int_bot: intern(Type::Int(Int::Bot)), - ty_int_top: intern(Type::Int(Int::Top)), - ty_if_both: intern(Type::Tuple { + bot: intern(Type::Bot), + top: intern(Type::Top), + ctrl: ty_ctrl, + xctrl: ty_xctrl, + int_zero: intern(Type::Int(Int::Constant(0))), + int_one: intern(Type::Int(Int::Constant(1))), + int_two: intern(Type::Int(Int::Constant(2))), + int_bot: intern(Type::Int(Int::Bot)), + int_top: intern(Type::Int(Int::Top)), + if_both: intern(Type::Tuple { types: arena.alloc([ty_ctrl, ty_ctrl]), }), - ty_if_neither: intern(Type::Tuple { + if_neither: intern(Type::Tuple { types: arena.alloc([ty_xctrl, ty_xctrl]), }), - ty_if_true: intern(Type::Tuple { + if_true: intern(Type::Tuple { types: arena.alloc([ty_ctrl, ty_xctrl]), }), - ty_if_false: intern(Type::Tuple { + if_false: intern(Type::Tuple { types: arena.alloc([ty_xctrl, ty_ctrl]), }), - ty_struct_bot, - ty_struct_top, - ty_memory_bot: intern(Type::Memory(Mem::Bot)), - ty_memory_top: intern(Type::Memory(Mem::Top)), - ty_pointer_bot: intern(Type::Pointer(MemPtr { + struct_bot: ty_struct_bot, + struct_top: ty_struct_top, + memory_bot: intern(Type::Memory(Mem::Bot)), + memory_top: intern(Type::Memory(Mem::Top)), + pointer_bot: intern(Type::Pointer(MemPtr { to: ty_struct_bot, nil: true, })), - ty_pointer_top: intern(Type::Pointer(MemPtr { + pointer_top: intern(Type::Pointer(MemPtr { to: ty_struct_top, nil: false, })), - ty_pointer_null: intern(Type::Pointer(MemPtr { + pointer_null: intern(Type::Pointer(MemPtr { to: ty_struct_top, nil: true, })), - ty_pointer_void: intern(Type::Pointer(MemPtr { + pointer_void: intern(Type::Pointer(MemPtr { to: ty_struct_bot, nil: false, })), @@ -116,9 +116,9 @@ impl<'a> Types<'a> { pub fn get_int(&self, value: i64) -> Ty<'a> { match value { - 0 => self.ty_int_zero, - 1 => self.ty_int_one, - 2 => self.ty_int_two, + 0 => self.int_zero, + 1 => self.int_one, + 2 => self.int_two, _ => self.interner.intern(Type::Int(Int::Constant(value))), } } @@ -169,7 +169,7 @@ impl<'a> Types<'a> { (Int::Bot, _) | (_, Int::Top) => a, (_, Int::Bot) | (Int::Top, _) => b, (Int::Constant(ca), Int::Constant(cb)) if ca == cb => a, - _ => self.ty_int_bot, + _ => self.int_bot, }, // Tuple sub-lattice @@ -204,7 +204,7 @@ impl<'a> Types<'a> { }).collect::>(); self.get_struct(na, &fields) } - _ => self.ty_struct_bot, // It's a struct; that's about all we know + _ => self.struct_bot, // It's a struct; that's about all we know }, // Pointer sub-lattice @@ -216,11 +216,11 @@ impl<'a> Types<'a> { (Type::Memory(ma), Type::Memory(mb)) => match (ma, mb) { (Mem::Bot, _) | (_, Mem::Top) => a, (_, Mem::Bot) | (Mem::Top, _) => b, - _ => self.ty_memory_bot, + _ => self.memory_bot, }, // different sub-lattices meet at bottom - _ => self.ty_bot, + _ => self.bot, } } @@ -241,21 +241,21 @@ impl<'a> Types<'a> { pub fn dual(&self, ty: Ty<'a>) -> Ty<'a> { match *ty { - Type::Bot => self.ty_top, - Type::Top => self.ty_bot, - Type::Ctrl => self.ty_xctrl, - Type::XCtrl => self.ty_ctrl, + Type::Bot => self.top, + Type::Top => self.bot, + Type::Ctrl => self.xctrl, + Type::XCtrl => self.ctrl, Type::Int(i) => match i { - Int::Bot => self.ty_int_top, - Int::Top => self.ty_int_bot, + Int::Bot => self.int_top, + Int::Top => self.int_bot, Int::Constant(_) => ty, // self dual }, Type::Tuple { types } => { self.get_tuple_from_slice(&types.iter().map(|t| self.dual(*t)).collect::>()) } Type::Struct(s) => match s { - Struct::Bot => self.ty_struct_top, - Struct::Top => self.ty_struct_bot, + Struct::Bot => self.struct_top, + Struct::Top => self.struct_bot, Struct::Struct { name, fields } => { let fields = fields .iter() @@ -269,8 +269,8 @@ impl<'a> Types<'a> { self.get_pointer(to, !p.nil) } Type::Memory(m) => match m { - Mem::Bot => self.ty_memory_top, - Mem::Top => self.ty_memory_bot, + Mem::Bot => self.memory_top, + Mem::Top => self.memory_bot, Mem::Alias(_) => ty, // self dual }, } @@ -279,10 +279,10 @@ impl<'a> Types<'a> { /// compute greatest lower bound in the lattice pub fn glb(&self, ty: Ty<'a>) -> Ty<'a> { match *ty { - Type::Bot | Type::Top => self.ty_bot, - Type::Ctrl => self.ty_xctrl, // why? - Type::XCtrl => self.ty_bot, // why? - Type::Int(_) => self.ty_int_bot, + Type::Bot | Type::Top => self.bot, + Type::Ctrl => self.xctrl, // why? + Type::XCtrl => self.bot, // why? + Type::Int(_) => self.int_bot, Type::Tuple { types } => { let types = types.iter().map(|&ty| self.glb(ty)).collect::>(); self.get_tuple_from_slice(&types) @@ -299,14 +299,14 @@ impl<'a> Types<'a> { } }, Type::Pointer(MemPtr { to, .. }) => self.get_pointer(self.glb(to), true), - Type::Memory(_) => self.ty_memory_bot, + Type::Memory(_) => self.memory_bot, } } pub fn make_init(&self, t: Ty<'a>) -> Option> { match *t { - Type::Int(_) => Some(self.ty_int_zero), - Type::Pointer(_) => Some(self.ty_pointer_null), + Type::Int(_) => Some(self.int_zero), + Type::Pointer(_) => Some(self.pointer_null), _ => None, } }