1#![doc = include_str!("../README.md")]
2
3pub mod ds;
4pub(crate) mod etc;
5pub(crate) mod semantic;
6pub(crate) mod syntax;
7
8pub use etc::util::{cargo_crate_name, get_crate_name, set_crate_name, PathSegments};
25pub use logic_eval::{Intern, Name, Term};
26pub use semantic::{
27 analyze::{Analyzer, Semantics},
28 entry::{AnalysisSession, Analyzed, Config, ConfigLoad, GlobalCx},
29 eval::Evaluated,
30 helper,
31 logic::{term, ImplLogic, Logic},
32 tree::{
33 pub_filter as filter, ArrayLen, Brief, NodeIndex, PathId, PubPathTree as PathTree, Type,
34 TypeArray, TypeId, TypeMut, TypePath, TypeRef, TypeScalar, TypeTuple, UniqueTypes,
35 },
36};
37pub use syntax::common::{AttributeHelper, IdentifySyn, SynId};
38
39pub mod item {
40 pub use super::semantic::tree::{
41 Block, Const, Field, Fn, Local, Mod, Param, PubItem as Item, Struct, Trait, TypeAlias, Use,
42 };
43}
44pub mod value {
45 pub use super::semantic::eval::{ConstGeneric, Enum, Field, Fn, Scalar, Value};
46}
47pub mod locator {
48 pub use syn_locator::{clear, enable_thread_local};
49}
50
51use std::{
52 collections::{HashMap, HashSet},
53 error::Error as StdError,
54 result::Result as StdResult,
55 sync::{Mutex, MutexGuard},
56};
57
58pub type Result<T> = StdResult<T, Error>;
59pub type Error = Box<dyn StdError + Send + Sync>;
60pub type TriResult<T, Se> = StdResult<T, TriError<Se>>;
61pub(crate) type SharedLock<T> = Mutex<T>;
62pub(crate) type SharedLockGuard<'a, T> = MutexGuard<'a, T>;
63
64#[derive(Debug)]
65pub enum TriError<Se> {
66 Soft(Se),
67 Hard(Box<dyn StdError + Send + Sync>),
68}
69
70pub trait TriResultHelper<T, S> {
71 fn on_soft_err<F: FnOnce(S) -> Result<T>>(self, f: F) -> Result<T>;
72
73 fn map_soft_err<F: FnOnce(S) -> U, U>(self, f: F) -> TriResult<T, U>;
74
75 fn elevate_err(self) -> Result<T>;
77}
78
79impl<T, S> TriResultHelper<T, S> for TriResult<T, S> {
80 fn on_soft_err<F: FnOnce(S) -> Result<T>>(self, f: F) -> Result<T> {
81 match self {
82 Ok(t) => Ok(t),
83 Err(TriError::Soft(s)) => f(s),
84 Err(TriError::Hard(e)) => Err(e),
85 }
86 }
87
88 fn map_soft_err<F: FnOnce(S) -> U, U>(self, f: F) -> TriResult<T, U> {
89 match self {
90 Ok(t) => Ok(t),
91 Err(TriError::Soft(s)) => Err(TriError::Soft(f(s))),
92 Err(TriError::Hard(e)) => Err(TriError::Hard(e)),
93 }
94 }
95
96 fn elevate_err(self) -> Result<T> {
97 match self {
98 Ok(t) => Ok(t),
99 Err(TriError::Soft(_)) => Err("elavated soft error".into()),
100 Err(TriError::Hard(e)) => Err(e),
101 }
102 }
103}
104
105impl<S> From<Error> for TriError<S> {
106 fn from(value: Error) -> Self {
107 Self::Hard(value)
108 }
109}
110
111#[macro_export]
112macro_rules! err {
113 (soft, $expr:expr) => {
114 Err( $crate::error!(soft, $expr) )
115 };
116 (hard, $($t:tt)*) => {
117 Err( $crate::error!(hard, $($t)*) )
118 };
119 ($($t:tt)*) => {
120 Err( $crate::error!($($t)*) )
121 };
122}
123
124#[macro_export]
125macro_rules! error {
126 (soft, $expr:expr) => {
127 $crate::TriError::Soft($expr)
128 };
129 (hard, $($t:tt)*) => {
130 $crate::TriError::Hard( format!($($t)*).into() )
131 };
132 ($($t:tt)*) => {
133 $crate::Error::from( format!($($t)*) )
134 };
135}
136
137#[macro_export]
138macro_rules! log {
139 (E, $($t:tt)*) => {{
140 if log::log_enabled!(log::Level::Error) {
141 log::error!($($t)*);
142 }
143 }};
144 (W, $($t:tt)*) => {{
145 if log::log_enabled!(log::Level::Warn) {
146 log::warn!($($t)*);
147 }
148 }};
149 (I, $($t:tt)*) => {{
150 if log::log_enabled!(log::Level::Info) {
151 log::info!($($t)*);
152 }
153 }};
154 (D, $($t:tt)*) => {{
155 if log::log_enabled!(log::Level::Debug) {
156 log::debug!($($t)*);
157 }
158 }};
159 (T, $($t:tt)*) => {{
160 if log::log_enabled!(log::Level::Trace) {
161 log::trace!($($t)*);
162 }
163 }};
164}
165
166#[macro_export]
167macro_rules! print {
168 ($($t:tt)*) => {
169 println!(
170 "@ {}\n┗ {}",
171 $crate::cur_path!(),
172 format!($($t)*)
173 )
174 };
175}
176
177#[macro_export]
178macro_rules! cur_path {
179 () => {{
180 struct S;
181 let s = std::any::type_name::<S>();
182 &s[..s.len() - 3]
183 }};
184}
185
186#[macro_export]
187macro_rules! pnode {
188 ($ptree:expr, $($path:tt)*) => {{
189 let key = format!($($path)*);
190 let Some(node) = $ptree.search($crate::PathTree::ROOT, key.as_str()) else {
191 panic!("failed to find the given path: `{}`", format!($($path)*));
192 };
193 node
194 }};
195}
196
197#[macro_export]
198macro_rules! pid {
199 ($ptree:expr, $($path:tt)*) => {{
200 let node = $crate::pnode!($ptree, $($path)*);
201 let (ii, _) = $ptree.node(node)
202 .iter()
203 .next()
204 .unwrap();
205 node.to_path_id(ii)
206 }};
207}
208
209#[macro_export]
210macro_rules! pitem {
211 ($ptree:expr, $($path:tt)*) => {{
212 let pid = $crate::pid!($ptree, $($path)*);
213 &$ptree.item(pid)
214 }};
215}
216
217pub type Map<K, V> = HashMap<K, V, fxhash::FxBuildHasher>;
220pub type Set<T> = HashSet<T, fxhash::FxBuildHasher>;
221
222#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
225pub enum Which2<A, B> {
226 A(A),
227 B(B),
228}
229
230#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
233pub enum Which3<A, B, C> {
234 A(A),
235 B(B),
236 C(C),
237}
238
239impl<A, B, C, VA> FromIterator<Which3<A, B, C>> for Which3<VA, B, C>
240where
241 VA: FromIterator<A>,
242{
243 fn from_iter<T: IntoIterator<Item = Which3<A, B, C>>>(iter: T) -> Self {
244 let mut filtered = None;
245 let va = iter
246 .into_iter()
247 .map(|which| match which {
248 Which3::A(a) => Some(a),
249 Which3::B(b) => {
250 filtered = Some(Which3::B(b));
251 None
252 }
253 Which3::C(c) => {
254 filtered = Some(Which3::C(c));
255 None
256 }
257 })
258 .take_while(|opt| opt.is_some())
259 .map(|opt| opt.unwrap())
260 .collect::<VA>();
261
262 if let Some(filtered) = filtered {
263 return filtered;
264 }
265
266 Which3::A(va)
267 }
268}
269
270#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
273pub enum TriOption<T, U> {
274 Some(T),
275 NotYet(U),
276 None,
277}
278
279impl<T, U> TryFrom<TriOption<T, U>> for Option<T> {
280 type Error = Error;
281
282 fn try_from(value: TriOption<T, U>) -> Result<Self> {
283 match value {
284 TriOption::Some(t) => Ok(Some(t)),
285 TriOption::NotYet(_) => err!("`TriOption::NotYet` cannot become `Option`"),
286 TriOption::None => Ok(None),
287 }
288 }
289}
290
291pub trait GetOwned<Id> {
294 type Owned;
295 fn get_owned(&self, id: Id) -> Self::Owned;
296}
297
298pub(crate) type NameIn<'a> = logic_eval::Name<any_intern::Interned<'a, str>>;
301pub(crate) type TermIn<'a> = logic_eval::Term<NameIn<'a>>;
302pub(crate) type ExprIn<'a> = logic_eval::Expr<NameIn<'a>>;
303pub(crate) type ClauseIn<'a> = logic_eval::Clause<NameIn<'a>>;
304pub(crate) type PredicateIn<'a> = logic_eval::Predicate<NameIn<'a>>;