use egglog_ast::generic_ast::GenericExpr;
use std::fmt::{Display, Formatter};
use std::hash::Hash;
use std::hash::Hasher;
use crate::ast::CorrespondingVar;
use crate::core::ResolvedCall;
use crate::{ArcSort, sort};
#[derive(Debug, Clone)]
pub struct ResolvedVar {
pub name: String,
pub sort: ArcSort,
pub is_global_ref: bool,
}
impl PartialEq for ResolvedVar {
fn eq(&self, other: &Self) -> bool {
self.name == other.name && self.sort.name() == other.sort.name()
}
}
impl Eq for ResolvedVar {}
impl Hash for ResolvedVar {
fn hash<H: Hasher>(&self, state: &mut H) {
self.name.hash(state);
self.sort.name().hash(state);
}
}
impl Display for ResolvedVar {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let display_name = crate::util::sanitize_internal_name(&self.name);
write!(f, "{}", display_name)
}
}
pub type Expr = GenericExpr<String, String>;
pub type ResolvedExpr = GenericExpr<ResolvedCall, ResolvedVar>;
pub(crate) type MappedExpr<Head, Leaf> = GenericExpr<CorrespondingVar<Head, Leaf>, Leaf>;
pub(crate) trait ResolvedExprExt {
fn output_type(&self) -> ArcSort;
fn get_global_var(&self) -> Option<ResolvedVar>;
}
impl ResolvedExprExt for ResolvedExpr {
fn output_type(&self) -> ArcSort {
match self {
ResolvedExpr::Lit(_, lit) => sort::literal_sort(lit),
ResolvedExpr::Var(_, resolved_var) => resolved_var.sort.clone(),
ResolvedExpr::Call(_, resolved_call, _) => resolved_call.output().clone(),
}
}
fn get_global_var(&self) -> Option<ResolvedVar> {
match self {
ResolvedExpr::Var(_, v) if v.is_global_ref => Some(v.clone()),
_ => None,
}
}
}
#[macro_export]
macro_rules! call {
($func:expr, $args:expr) => {
$crate::ast::GenericExpr::Call($crate::span!(), $func.into(), $args.into_iter().collect())
};
}
#[macro_export]
macro_rules! lit {
($lit:expr) => {
$crate::ast::GenericExpr::Lit($crate::span!(), $lit.into())
};
}
#[macro_export]
macro_rules! var {
($var:expr) => {
$crate::ast::GenericExpr::Var($crate::span!(), $var.into())
};
}
pub use {call, lit, var};