dpc/common/
condition.rs

1use super::mc::pos::IntCoordinates;
2use super::mc::EntityTarget;
3use super::reg::GetUsedRegs;
4use super::val::{MutableValue, Value};
5use super::{Identifier, ResourceLocation, ResourceLocationTag};
6use std::fmt::Debug;
7use std::iter;
8
9/// Condition for if and other IR instructions
10#[derive(Clone, PartialEq)]
11pub enum Condition {
12	Not(Box<Condition>),
13	And(Box<Condition>, Box<Condition>),
14	Or(Box<Condition>, Box<Condition>),
15	Xor(Box<Condition>, Box<Condition>),
16	Equal(Value, Value),
17	Exists(Value),
18	GreaterThan(Value, Value),
19	GreaterThanOrEqual(Value, Value),
20	LessThan(Value, Value),
21	LessThanOrEqual(Value, Value),
22	Bool(Value),
23	NotBool(Value),
24	Entity(EntityTarget),
25	Predicate(ResourceLocation),
26	Biome(IntCoordinates, ResourceLocationTag),
27	Loaded(IntCoordinates),
28	Dimension(ResourceLocation),
29	Function(ResourceLocationTag),
30}
31
32impl Condition {
33	pub fn iter_used_regs_mut(&mut self) -> Box<dyn Iterator<Item = &mut Identifier> + '_> {
34		match self {
35			Self::Equal(l, r)
36			| Self::GreaterThan(l, r)
37			| Self::GreaterThanOrEqual(l, r)
38			| Self::LessThan(l, r)
39			| Self::LessThanOrEqual(l, r) => Box::new(
40				l.get_used_regs_mut()
41					.into_iter()
42					.chain(r.get_used_regs_mut()),
43			),
44			Self::Exists(val) | Self::Bool(val) | Self::NotBool(val) => {
45				Box::new(val.get_used_regs_mut().into_iter())
46			}
47			Self::Not(condition) => condition.iter_used_regs_mut(),
48			Self::And(l, r) | Self::Or(l, r) | Self::Xor(l, r) => {
49				Box::new(l.iter_used_regs_mut().chain(r.iter_used_regs_mut()))
50			}
51			Self::Entity(..)
52			| Self::Predicate(..)
53			| Self::Biome(..)
54			| Self::Loaded(..)
55			| Self::Dimension(..)
56			| Self::Function(..) => Box::new(iter::empty()),
57		}
58	}
59
60	pub fn iter_mut_vals(&mut self) -> Box<dyn Iterator<Item = &mut MutableValue> + '_> {
61		match self {
62			Self::Equal(l, r)
63			| Self::GreaterThan(l, r)
64			| Self::GreaterThanOrEqual(l, r)
65			| Self::LessThan(l, r)
66			| Self::LessThanOrEqual(l, r) => Box::new(l.iter_mut_val().into_iter().chain(r.iter_mut_val())),
67			Self::Exists(val) | Self::Bool(val) | Self::NotBool(val) => {
68				Box::new(val.iter_mut_val().into_iter())
69			}
70			Self::Not(condition) => condition.iter_mut_vals(),
71			Self::And(l, r) | Self::Xor(l, r) | Self::Or(l, r) => {
72				Box::new(l.iter_mut_vals().chain(r.iter_mut_vals()))
73			}
74			Self::Entity(..)
75			| Self::Predicate(..)
76			| Self::Biome(..)
77			| Self::Loaded(..)
78			| Self::Dimension(..)
79			| Self::Function(..) => Box::new(iter::empty()),
80		}
81	}
82
83	pub fn has_side_effects(&self) -> bool {
84		match self {
85			Self::Function(..) => true,
86			_ => false,
87		}
88	}
89}
90
91impl GetUsedRegs for Condition {
92	fn append_used_regs<'a>(&'a self, regs: &mut Vec<&'a Identifier>) {
93		match self {
94			Self::Equal(l, r)
95			| Self::GreaterThan(l, r)
96			| Self::GreaterThanOrEqual(l, r)
97			| Self::LessThan(l, r)
98			| Self::LessThanOrEqual(l, r) => {
99				l.append_used_regs(regs);
100				r.append_used_regs(regs);
101			}
102			Self::Exists(val) | Self::Bool(val) | Self::NotBool(val) => {
103				val.append_used_regs(regs);
104			}
105			Self::Not(condition) => {
106				condition.append_used_regs(regs);
107			}
108			Self::And(l, r) | Self::Or(l, r) | Self::Xor(l, r) => {
109				l.append_used_regs(regs);
110				r.append_used_regs(regs);
111			}
112			Self::Entity(..)
113			| Self::Predicate(..)
114			| Self::Biome(..)
115			| Self::Loaded(..)
116			| Self::Dimension(..)
117			| Self::Function(..) => {}
118		}
119	}
120}
121
122impl Debug for Condition {
123	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
124		match self {
125			Self::Equal(l, r) => write!(f, "{l:?} == {r:?}"),
126			Self::Exists(val) => write!(f, "exi {val:?}"),
127			Self::Not(condition) => write!(f, "not {condition:?}"),
128			Self::And(l, r) => write!(f, "and {l:?} {r:?}"),
129			Self::Or(l, r) => write!(f, "or {l:?} {r:?}"),
130			Self::Xor(l, r) => write!(f, "xor {l:?} {r:?}"),
131			Self::GreaterThan(l, r) => write!(f, "{l:?} > {r:?}"),
132			Self::GreaterThanOrEqual(l, r) => write!(f, "{l:?} >= {r:?}"),
133			Self::LessThan(l, r) => write!(f, "{l:?} < {r:?}"),
134			Self::LessThanOrEqual(l, r) => write!(f, "{l:?} <= {r:?}"),
135			Self::Bool(val) => write!(f, "bool {val:?}"),
136			Self::NotBool(val) => write!(f, "nbool {val:?}"),
137			Self::Entity(ent) => write!(f, "ent {ent:?}"),
138			Self::Predicate(pred) => write!(f, "pred {pred:?}"),
139			Self::Biome(loc, biome) => write!(f, "bio {loc:?} {biome}"),
140			Self::Loaded(loc) => write!(f, "load {loc:?}"),
141			Self::Dimension(dim) => write!(f, "dim {dim}"),
142			Self::Function(func) => write!(f, "fn {func}"),
143		}
144	}
145}