use super::NodeId;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum CompilerENode {
Int(i64),
Bool(bool),
Float(u64),
Var(u32, u32),
Opaque(u32),
Add(NodeId, NodeId),
Sub(NodeId, NodeId),
Mul(NodeId, NodeId),
Div(NodeId, NodeId),
Mod(NodeId, NodeId),
Shl(NodeId, NodeId),
Shr(NodeId, NodeId),
BitXor(NodeId, NodeId),
BitAnd(NodeId, NodeId),
BitOr(NodeId, NodeId),
And(NodeId, NodeId),
Or(NodeId, NodeId),
Not(NodeId),
Eq(NodeId, NodeId),
Ne(NodeId, NodeId),
Lt(NodeId, NodeId),
Le(NodeId, NodeId),
Gt(NodeId, NodeId),
Ge(NodeId, NodeId),
Concat(NodeId, NodeId),
Len(NodeId),
Index(NodeId, NodeId),
Copy(NodeId),
Slice(NodeId, NodeId, NodeId),
Contains(NodeId, NodeId),
}
impl CompilerENode {
pub fn children(&self) -> Vec<NodeId> {
use CompilerENode::*;
match *self {
Int(_) | Bool(_) | Float(_) | Var(..) | Opaque(_) => vec![],
Not(a) | Len(a) | Copy(a) => vec![a],
Add(a, b) | Sub(a, b) | Mul(a, b) | Div(a, b) | Mod(a, b) | Shl(a, b)
| Shr(a, b) | BitXor(a, b) | BitAnd(a, b) | BitOr(a, b) | And(a, b) | Or(a, b)
| Eq(a, b) | Ne(a, b) | Lt(a, b) | Le(a, b) | Gt(a, b) | Ge(a, b)
| Concat(a, b) | Index(a, b) | Contains(a, b) => {
vec![a, b]
}
Slice(a, b, c) => vec![a, b, c],
}
}
pub fn map_children(self, mut f: impl FnMut(NodeId) -> NodeId) -> Self {
use CompilerENode::*;
match self {
Int(_) | Bool(_) | Float(_) | Var(..) | Opaque(_) => self,
Not(a) => Not(f(a)),
Len(a) => Len(f(a)),
Add(a, b) => Add(f(a), f(b)),
Sub(a, b) => Sub(f(a), f(b)),
Mul(a, b) => Mul(f(a), f(b)),
Div(a, b) => Div(f(a), f(b)),
Mod(a, b) => Mod(f(a), f(b)),
Shl(a, b) => Shl(f(a), f(b)),
Shr(a, b) => Shr(f(a), f(b)),
BitXor(a, b) => BitXor(f(a), f(b)),
BitAnd(a, b) => BitAnd(f(a), f(b)),
BitOr(a, b) => BitOr(f(a), f(b)),
And(a, b) => And(f(a), f(b)),
Or(a, b) => Or(f(a), f(b)),
Eq(a, b) => Eq(f(a), f(b)),
Ne(a, b) => Ne(f(a), f(b)),
Lt(a, b) => Lt(f(a), f(b)),
Le(a, b) => Le(f(a), f(b)),
Gt(a, b) => Gt(f(a), f(b)),
Ge(a, b) => Ge(f(a), f(b)),
Concat(a, b) => Concat(f(a), f(b)),
Index(a, b) => Index(f(a), f(b)),
Copy(a) => Copy(f(a)),
Slice(a, b, c) => Slice(f(a), f(b), f(c)),
Contains(a, b) => Contains(f(a), f(b)),
}
}
pub fn op_is_total(&self) -> bool {
!matches!(
self,
CompilerENode::Div(..)
| CompilerENode::Mod(..)
| CompilerENode::Index(..)
| CompilerENode::Slice(..)
| CompilerENode::Len(..)
| CompilerENode::Copy(..)
| CompilerENode::Contains(..)
| CompilerENode::Opaque(_)
)
}
}