ferrum_compiler/syntax/
mod.rs

1mod decl;
2pub use decl::*;
3
4mod expr;
5pub use expr::*;
6
7mod node;
8pub use node::*;
9
10mod stmt;
11pub use stmt::*;
12
13mod r#use;
14pub use r#use::*;
15
16mod r#static;
17pub use r#static::*;
18
19use crate::config::Config;
20use crate::log;
21use crate::r#type::FeType;
22use crate::result::Result;
23use crate::token;
24use crate::utils::{fe_from, fe_try_from};
25
26use std::collections::HashMap;
27use std::path::PathBuf;
28use std::sync::{Arc, Mutex};
29
30pub trait SyntaxCompiler<IR> {
31    fn compile_package(cfg: Arc<Config>, entry: Arc<Mutex<FeSyntaxPackage<FeType>>>) -> Result<IR>;
32}
33
34pub trait Resolvable {
35    fn is_signature_resolved(&self) -> bool {
36        return self.is_resolved();
37    }
38
39    fn is_resolved(&self) -> bool;
40}
41
42#[derive(Debug, Clone)]
43pub enum FeSyntaxPackage<T: ResolvedType = ()> {
44    File(FeSyntaxFile<T>),
45    Dir(FeSyntaxDir<T>),
46}
47
48impl From<token::FeTokenPackage> for FeSyntaxPackage {
49    fn from(value: token::FeTokenPackage) -> Self {
50        match value {
51            token::FeTokenPackage::File(file) => return FeSyntaxPackage::File(file.into()),
52            token::FeTokenPackage::Dir(dir) => return FeSyntaxPackage::Dir(dir.into()),
53        };
54    }
55}
56
57impl<T: ResolvedType> From<FeSyntaxPackage<()>> for FeSyntaxPackage<Option<T>> {
58    fn from(value: FeSyntaxPackage<()>) -> Self {
59        match value {
60            FeSyntaxPackage::File(file) => return Self::File(file.into()),
61            FeSyntaxPackage::Dir(dir) => return Self::Dir(dir.into()),
62        }
63    }
64}
65
66impl<T: ResolvedType> Resolvable for FeSyntaxPackage<Option<T>> {
67    fn is_resolved(&self) -> bool {
68        match self {
69            Self::File(file) => return file.is_resolved(),
70            Self::Dir(dir) => return dir.is_resolved(),
71        }
72    }
73}
74
75impl<T: ResolvedType> TryFrom<FeSyntaxPackage<Option<T>>> for FeSyntaxPackage<T> {
76    type Error = FinalizeResolveTypeError;
77
78    fn try_from(value: FeSyntaxPackage<Option<T>>) -> Result<Self, Self::Error> {
79        match value {
80            FeSyntaxPackage::File(file) => {
81                return Ok(FeSyntaxPackage::File(file.try_into()?));
82            }
83            FeSyntaxPackage::Dir(dir) => return Ok(FeSyntaxPackage::Dir(dir.try_into()?)),
84        }
85    }
86}
87
88#[derive(Debug, Clone)]
89pub struct FeSyntaxFile<T: ResolvedType = ()> {
90    pub name: SyntaxPackageName,
91    pub path: PathBuf,
92    pub syntax: Arc<Mutex<SyntaxTree<T>>>,
93}
94
95impl From<token::FeTokenFile> for FeSyntaxFile {
96    fn from(value: token::FeTokenFile) -> Self {
97        return Self {
98            name: value.name.into(),
99            path: value.path,
100            syntax: Arc::new(Mutex::new(SyntaxTree {
101                mods: vec![],
102                uses: vec![],
103                decls: vec![],
104            })),
105        };
106    }
107}
108
109impl<T: ResolvedType> From<FeSyntaxFile<()>> for FeSyntaxFile<Option<T>> {
110    fn from(value: FeSyntaxFile<()>) -> Self {
111        return Self {
112            name: value.name,
113            path: value.path,
114            syntax: fe_from(value.syntax),
115        };
116    }
117}
118
119impl<T: ResolvedType> Resolvable for FeSyntaxFile<Option<T>> {
120    fn is_resolved(&self) -> bool {
121        return self.syntax.lock().unwrap().is_resolved();
122    }
123}
124
125impl<T: ResolvedType> TryFrom<FeSyntaxFile<Option<T>>> for FeSyntaxFile<T> {
126    type Error = FinalizeResolveTypeError;
127
128    fn try_from(value: FeSyntaxFile<Option<T>>) -> Result<Self, Self::Error> {
129        return Ok(Self {
130            name: value.name,
131            path: value.path,
132            syntax: fe_try_from(value.syntax)?,
133        });
134    }
135}
136
137#[derive(Debug, Clone)]
138pub struct FeSyntaxDir<T: ResolvedType = ()> {
139    pub name: SyntaxPackageName,
140    pub path: PathBuf,
141    pub entry_file: FeSyntaxFile<T>,
142    pub local_packages: HashMap<SyntaxPackageName, Arc<Mutex<FeSyntaxPackage<T>>>>,
143}
144
145impl From<token::FeTokenDir> for FeSyntaxDir {
146    fn from(value: token::FeTokenDir) -> Self {
147        return Self {
148            name: value.name.into(),
149            path: value.path,
150            entry_file: value.entry_file.into(),
151            local_packages: value
152                .local_packages
153                .into_iter()
154                .map(|(name, pkg)| (name.into(), fe_from(pkg)))
155                .collect(),
156        };
157    }
158}
159
160impl<T: ResolvedType> From<FeSyntaxDir<()>> for FeSyntaxDir<Option<T>> {
161    fn from(value: FeSyntaxDir<()>) -> Self {
162        let local_packages = value
163            .local_packages
164            .into_iter()
165            .map(|(name, pkg)| (name, fe_from(pkg)))
166            .collect();
167
168        return Self {
169            name: value.name,
170            path: value.path,
171            entry_file: value.entry_file.into(),
172            local_packages,
173        };
174    }
175}
176
177impl<T: ResolvedType> Resolvable for FeSyntaxDir<Option<T>> {
178    fn is_resolved(&self) -> bool {
179        if !self.entry_file.is_resolved() {
180            return log::trace!(false);
181        }
182
183        for pkg in self.local_packages.values() {
184            if !pkg.lock().unwrap().is_resolved() {
185                return log::trace!(false);
186            }
187        }
188
189        return true;
190    }
191}
192
193impl<T: ResolvedType> TryFrom<FeSyntaxDir<Option<T>>> for FeSyntaxDir<T> {
194    type Error = FinalizeResolveTypeError;
195
196    fn try_from(value: FeSyntaxDir<Option<T>>) -> Result<Self, Self::Error> {
197        let local_packages = value
198            .local_packages
199            .into_iter()
200            .map(|(name, pkg)| Ok((name, fe_try_from(pkg)?)))
201            .collect::<Result<
202                HashMap<SyntaxPackageName, Arc<Mutex<FeSyntaxPackage<T>>>>,
203                FinalizeResolveTypeError,
204            >>()?;
205
206        return Ok(FeSyntaxDir {
207            name: value.name,
208            path: value.path,
209            entry_file: value.entry_file.try_into()?,
210            local_packages,
211        });
212    }
213}
214
215#[derive(Debug, Clone, Hash, PartialEq, Eq)]
216pub struct SyntaxPackageName(pub Arc<str>);
217
218impl From<token::TokenPackageName> for SyntaxPackageName {
219    fn from(value: token::TokenPackageName) -> Self {
220        return Self(value.0);
221    }
222}
223
224#[derive(Debug, Clone)]
225pub struct SyntaxTree<T: ResolvedType = ()> {
226    pub mods: Vec<Mod>,
227    pub uses: Vec<Arc<Mutex<Use<T>>>>,
228    pub decls: Vec<Arc<Mutex<Decl<T>>>>,
229}
230
231impl<T: ResolvedType> From<SyntaxTree<()>> for SyntaxTree<Option<T>> {
232    fn from(value: SyntaxTree<()>) -> Self {
233        return Self {
234            mods: value.mods,
235            uses: value.uses.into_iter().map(fe_from).collect(),
236            decls: value.decls.into_iter().map(fe_from).collect(),
237        };
238    }
239}
240
241impl<T: ResolvedType> Resolvable for SyntaxTree<Option<T>> {
242    fn is_resolved(&self) -> bool {
243        for u in &self.uses {
244            if !u.lock().unwrap().is_resolved() {
245                return log::trace!(false);
246            }
247        }
248
249        for d in &self.decls {
250            if !d.lock().unwrap().is_resolved() {
251                return log::trace!(false);
252            }
253        }
254
255        return true;
256    }
257}
258
259impl<T: ResolvedType> TryFrom<SyntaxTree<Option<T>>> for SyntaxTree<T> {
260    type Error = FinalizeResolveTypeError;
261
262    fn try_from(value: SyntaxTree<Option<T>>) -> Result<Self, Self::Error> {
263        return Ok(Self {
264            mods: value.mods,
265            uses: value
266                .uses
267                .into_iter()
268                .map(fe_try_from)
269                .collect::<Result<Vec<Arc<Mutex<Use<T>>>>, Self::Error>>()?,
270            decls: value
271                .decls
272                .into_iter()
273                .map(fe_try_from)
274                .collect::<Result<Vec<Arc<Mutex<Decl<T>>>>, Self::Error>>()?,
275        });
276    }
277}
278
279#[derive(Debug, Clone, PartialEq)]
280pub struct Mod(pub Arc<str>);
281
282#[derive(Debug, Clone)]
283pub struct FinalizeResolveTypeError {
284    pub file: &'static str,
285    pub line: u32,
286}
287
288impl std::fmt::Display for FinalizeResolveTypeError {
289    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
290        return write!(f, "{self:?}");
291    }
292}
293impl std::error::Error for FinalizeResolveTypeError {}
294
295pub trait ResolvedType: std::fmt::Debug + Clone + PartialEq {}
296impl ResolvedType for () {}
297impl ResolvedType for FeType {}
298impl<T: ResolvedType> ResolvedType for Option<T> {}
299
300pub trait IsTerminal<T: ResolvedType> {
301    fn is_terminal(&mut self) -> bool {
302        return false;
303    }
304}