diff --git a/Cargo.lock b/Cargo.lock index 92c691e..fff075e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,133 +82,6 @@ dependencies = [ "yansi", ] -[[package]] -name = "async-channel" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-executor" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8828ec6e544c02b0d6691d21ed9f9218d0384a82542855073c2a3f58304aaf0" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "slab", -] - -[[package]] -name = "async-fs" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" -dependencies = [ - "async-lock", - "blocking", - "futures-lite", -] - -[[package]] -name = "async-io" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" -dependencies = [ - "async-lock", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix", - "slab", - "tracing", - "windows-sys 0.52.0", -] - -[[package]] -name = "async-lock" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" -dependencies = [ - "event-listener", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-net" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" -dependencies = [ - "async-io", - "blocking", - "futures-lite", -] - -[[package]] -name = "async-process" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7eda79bbd84e29c2b308d1dc099d7de8dcc7035e48f4bf5dc4a531a44ff5e2a" -dependencies = [ - "async-channel", - "async-io", - "async-lock", - "async-signal", - "async-task", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "rustix", - "tracing", - "windows-sys 0.52.0", -] - -[[package]] -name = "async-signal" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794f185324c2f00e771cd9f1ae8b5ac68be2ca7abb129a87afd6e86d228bc54d" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if", - "futures-core", - "futures-io", - "rustix", - "signal-hook-registry", - "slab", - "windows-sys 0.52.0", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - [[package]] name = "autocfg" version = "1.1.0" @@ -248,19 +121,6 @@ dependencies = [ "serde", ] -[[package]] -name = "blocking" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" -dependencies = [ - "async-channel", - "async-task", - "futures-io", - "futures-lite", - "piper", -] - [[package]] name = "bytemuck" version = "1.14.0" @@ -331,15 +191,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "countme" version = "3.0.1" @@ -515,12 +366,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" -[[package]] -name = "easy-parallel" -version = "3.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2afbb9b0aef60e4f0d2b18129b6c0dff035a6f7dbbd17c2f38c1432102ee223c" - [[package]] name = "ego-tree" version = "0.6.2" @@ -560,16 +405,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "eval" version = "0.1.0" @@ -580,27 +415,6 @@ dependencies = [ "serde", ] -[[package]] -name = "event-listener" -version = "5.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" -dependencies = [ - "event-listener", - "pin-project-lite", -] - [[package]] name = "exr" version = "1.71.0" @@ -617,12 +431,6 @@ dependencies = [ "zune-inflate", ] -[[package]] -name = "fastrand" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" - [[package]] name = "fdeflate" version = "0.3.3" @@ -663,31 +471,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-lite" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - [[package]] name = "getrandom" version = "0.2.12" @@ -827,18 +610,14 @@ dependencies = [ "crossbeam", "dashmap", "drop_bomb", - "easy-parallel", "ego-tree", "enumset", - "futures-lite", "indexmap", "indoc", "logos", - "num_cpus", "owo-colors", "petgraph", "rowan", - "smol", ] [[package]] @@ -870,12 +649,6 @@ dependencies = [ "redox_syscall 0.4.1", ] -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - [[package]] name = "lock_api" version = "0.4.11" @@ -974,16 +747,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "num_threads" version = "0.1.6" @@ -1014,12 +777,6 @@ dependencies = [ "supports-color", ] -[[package]] -name = "parking" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" - [[package]] name = "parking_lot_core" version = "0.9.10" @@ -1085,23 +842,6 @@ dependencies = [ "siphasher", ] -[[package]] -name = "pin-project-lite" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "piper" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - [[package]] name = "png" version = "0.17.10" @@ -1115,21 +855,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "polling" -version = "3.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6a007746f34ed64099e88783b0ae369eaa3da6392868ba262e2af9b8fbaea1" -dependencies = [ - "cfg-if", - "concurrent-queue", - "hermit-abi", - "pin-project-lite", - "rustix", - "tracing", - "windows-sys 0.52.0", -] - [[package]] name = "powerfmt" version = "0.2.0" @@ -1274,19 +999,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "rustix" -version = "0.38.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" -dependencies = [ - "bitflags 2.4.1", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - [[package]] name = "ryu" version = "1.0.16" @@ -1330,15 +1042,6 @@ dependencies = [ "serde", ] -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - [[package]] name = "simd-adler32" version = "0.3.7" @@ -1351,38 +1054,12 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - [[package]] name = "smallvec" version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" -[[package]] -name = "smol" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e635339259e51ef85ac7aa29a1cd991b957047507288697a690e80ab97d07cad" -dependencies = [ - "async-channel", - "async-executor", - "async-fs", - "async-io", - "async-lock", - "async-net", - "async-process", - "blocking", - "futures-lite", -] - [[package]] name = "spin" version = "0.9.8" @@ -1486,22 +1163,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" - [[package]] name = "unicode-ident" version = "1.0.12" diff --git a/crates/lang/Cargo.toml b/crates/lang/Cargo.toml index f50073a..de54f2b 100644 --- a/crates/lang/Cargo.toml +++ b/crates/lang/Cargo.toml @@ -16,13 +16,9 @@ rowan = "0.15.15" drop_bomb = "0.1.5" enumset = "1.1.3" indoc = "2" -num_cpus = "1.16" dashmap = "5.5.3" crossbeam = "0.8.4" owo-colors = {version = "4", features = ["supports-colors"]} -smol = "2" -futures-lite = "2.3" -easy-parallel = "3.3.1" [lints] workspace = true diff --git a/crates/lang/src/ast.rs b/crates/lang/src/ast.rs deleted file mode 100644 index 0c63620..0000000 --- a/crates/lang/src/ast.rs +++ /dev/null @@ -1,72 +0,0 @@ -use std::{collections::HashMap, path::PathBuf}; - -use rowan::ast::{AstNode, AstPtr}; - -use self::{ - error::{Error, WorldCreationError}, - mod_tree::ModuleTree, - namespace::Registry, - source_file::SourceFile, -}; - -mod error; -mod mod_tree; -mod namespace; -mod nodes; -mod path; -mod source_file; - -#[derive(Debug)] -struct Loc { - file: PathBuf, - syntax_el: AstPtr, -} - -impl Loc { - pub fn new(file: PathBuf, syntax_el: &T) -> Self { - Self { - file, - syntax_el: AstPtr::new(syntax_el), - } - } - - pub fn file(&self) -> &PathBuf { - &self.file - } -} - -pub struct World { - entry_point: PathBuf, - files: HashMap, - errors: Vec, - module_tree: ModuleTree, - registry: Registry, -} - -impl World { - pub fn new(entry_point: PathBuf) -> Result { - let entry_point = entry_point.canonicalize().unwrap(); - let source = match std::fs::read_to_string(&entry_point) { - Ok(f) => f, - Err(e) => return Err(WorldCreationError::FailedToOpenEntryPoint(entry_point, e)), - }; - - let (src, mut errors) = SourceFile::parse_from(&entry_point, source); - - let (module_tree, mut files, new_errors, registry) = - ModuleTree::parse_from_main(&entry_point, &src); - errors.extend(new_errors); - module_tree.print_tree(&src.tree()); - dbg!(&errors); - - let _ = files.insert(entry_point.clone(), src); - - Ok(Self { - files, - entry_point, - errors, - module_tree, - registry, - }) - } -} diff --git a/crates/lang/src/ast/error.rs b/crates/lang/src/ast/error.rs deleted file mode 100644 index 352e831..0000000 --- a/crates/lang/src/ast/error.rs +++ /dev/null @@ -1,30 +0,0 @@ -use std::{fmt::Display, path::PathBuf}; - -use crate::lst_parser::error::SyntaxError; - -#[derive(Debug)] -pub enum Error { - Syntax(PathBuf, SyntaxError), - FailedToOpenFileMod(PathBuf, std::io::Error), -} - -impl Error { - pub fn from_syntax(file: PathBuf, e: SyntaxError) -> Self { - Self::Syntax(file, e) - } -} - -#[derive(Debug)] -pub enum WorldCreationError { - FailedToOpenEntryPoint(PathBuf, std::io::Error), -} - -impl Display for WorldCreationError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - WorldCreationError::FailedToOpenEntryPoint(entry_path, e) => { - write!(f, "failed to open entry_point '{entry_path:?}': {e}") - } - } - } -} diff --git a/crates/lang/src/ast/mod_tree.rs b/crates/lang/src/ast/mod_tree.rs deleted file mode 100644 index 2e5e269..0000000 --- a/crates/lang/src/ast/mod_tree.rs +++ /dev/null @@ -1,281 +0,0 @@ -use std::{ - cell::RefCell, - collections::HashMap, - path::{Path, PathBuf}, - rc::Rc, - sync::Arc, -}; - -use rowan::ast::{AstNode, SyntaxNodePtr}; - -use crate::{lst_parser::syntax_kind::SyntaxKind, Lang, SyntaxNode}; - -use super::{ - error::Error, - namespace::Registry, - nodes::{self, Mod, ModBody, ModName, Root}, - path::{ItemPath, OwnedItemPath}, - source_file::SourceFile, - Loc, -}; - -pub struct ModuleTree { - modules: Rc>>, -} - -#[derive(Clone)] -struct ModuleParsingContext { - files: Rc>>, - errors: Rc>>, - reg: Rc>, - proj_dir: Rc, - cur_path: Vec, - cur_file: PathBuf, -} - -impl ModuleParsingContext { - fn new(entry_path: &Path) -> Self { - let proj_dir = entry_path.parent().unwrap().to_owned(); - Self { - files: Rc::new(RefCell::new(HashMap::new())), - errors: Rc::new(RefCell::new(Vec::new())), - reg: Rc::new(RefCell::new(Registry::new())), - proj_dir: Rc::new(entry_path.to_owned()), - cur_path: Vec::new(), - cur_file: entry_path.to_owned(), - } - } - - fn entry_path(&self) -> PathBuf { - self.proj_dir.to_path_buf() - } - - fn make_mod_file_path(&self, mod_path: &[String], mod_name: &str) -> PathBuf { - let mut entry_path = self.entry_path(); - for el in mod_path { - entry_path.push(format!("{el}/")); - } - entry_path.push(format!("{mod_name}.owo")); - entry_path - } - - fn push_cur_path(&mut self, name_to_add: String) { - self.cur_path.push(name_to_add); - } - - fn set_cur_file(&mut self, new: PathBuf) { - self.cur_file = new; - } - - fn push_errs(&self, errs: Vec) { - self.errors.borrow_mut().extend(errs); - } - - fn parse_child_modules( - &self, - node: &SyntaxNode, - name: Option, - ) -> HashMap> { - let mut ctx = self.clone(); - if let Some(name) = name { - ctx.push_cur_path(name) - } - node.children() - .filter_map(Mod::cast) - .filter_map(|m| match Module::parse_mod(m, self.clone()) { - Ok(module) => Some((module.name(), module)), - Err(error) => { - self.errors.borrow_mut().push(error); - None - } - }) - .collect::>>() - } - - fn dissolve(self) -> (HashMap, Vec, Registry) { - let Self { - files, - errors, - mut reg, - .. - } = self; - (files.take(), errors.take(), (&*reg).take()) - } -} - -impl ModuleTree { - pub fn parse_from_main( - path: &PathBuf, - main_file: &SourceFile, - ) -> (Self, HashMap, Vec, Registry) { - let entry_path = path.parent().unwrap().to_owned(); - let ctx = ModuleParsingContext::new(&entry_path); - - let modules = Rc::new(ctx.parse_child_modules(main_file.tree().syntax(), None)); - - let (files, errors, reg) = ctx.dissolve(); - (Self { modules }, files, errors, reg) - } - - pub fn print_tree(&self, lst: &Root) { - let name = "main"; - print_tree(&name, self.modules.clone(), 0) - } -} - -#[derive(Debug)] -pub struct Module { - path: Vec, - name: String, - kind: ModuleKind, - children: Rc>>, - parent: Option>, - body: SyntaxNodePtr, -} - -impl Module { - fn parse_mod(module: Mod, mut ctx: ModuleParsingContext) -> Result, Error> { - let children = module - .syntax() - .children() - // .map(|n| n.kind()) - .collect::>(); - - let r; - if children.len() == 1 { - let name = &children[0]; - assert_eq!(name.kind(), SyntaxKind::MODULE_NAME); - r = Self::parse_file_mod( - name.text().to_string(), - ctx.clone(), - Loc::new(ctx.cur_file.clone(), &module), - ); - } else if children.len() == 2 { - let name = &children[0]; - assert_eq!(name.kind(), SyntaxKind::MODULE_NAME); - let body = &children[1]; - assert_eq!(body.kind(), SyntaxKind::MODULE_BODY); - r = Ok(Self::parse_inline_mod(module, ctx.clone())); - } else { - unreachable!() - } - r.map(|module| { - let rc = Rc::new(module); - ctx.reg.borrow_mut().insert_mod(rc.path(), rc.clone()); - rc - }) - } - - fn parse_file_mod( - name: String, - mut ctx: ModuleParsingContext, - decl: Loc, - ) -> Result { - ctx.set_cur_file(ctx.make_mod_file_path(&ctx.cur_path, &name)); - - let source = match std::fs::read_to_string(&ctx.cur_file) { - Ok(f) => f, - Err(e) => return Err(Error::FailedToOpenFileMod(ctx.cur_file, e)), - }; - - let (source_file, file_errors) = SourceFile::parse_from(&ctx.cur_file, source); - - let old_path = ctx.cur_path.clone(); - ctx.push_cur_path(name.clone()); - ctx.push_errs(file_errors); - - let children = - Rc::new(ctx.parse_child_modules(source_file.tree().syntax(), Some(name.clone()))); - let body = SyntaxNodePtr::new(source_file.tree().syntax()); - - ctx.files - .borrow_mut() - .insert(ctx.cur_file.clone(), source_file); - - Ok(Self { - path: old_path, - name, - kind: ModuleKind::File { - declaration: decl, - file_id: ctx.cur_file.clone(), - }, - children, - parent: None, - body, - }) - } - - fn parse_inline_mod(module: Mod, mut ctx: ModuleParsingContext) -> Self { - let mut children = module.syntax().children().collect::>(); - - let body = ModBody::cast(children.pop().unwrap()).unwrap(); - let name = ModName::cast(children.pop().unwrap()) - .unwrap() - .syntax() - .text() - .to_string(); - - let old_path = ctx.cur_path.clone(); - ctx.push_cur_path(name.clone()); - let children = Rc::new(ctx.parse_child_modules(body.syntax(), Some(name.clone()))); - - Self { - name, - kind: ModuleKind::Inline(Loc::new(ctx.cur_file.to_owned(), &module)), - children, - parent: None, - path: old_path, - body: SyntaxNodePtr::new(body.syntax()), - } - } - - pub fn path(&self) -> ItemPath { - let mut p = self.path.clone(); - p.push(self.name()); - let mut r_p = ItemPath::new(); - for i in p { - r_p = r_p.push(i); - } - r_p - } - - pub fn name(&self) -> String { - // self.name.to_node(lst.syntax()).syntax().text().to_string() - self.name.clone() - } - - pub fn body(&self, files: &HashMap) -> SyntaxNode { - match &self.kind { - ModuleKind::Inline(l) => { - let file = files.get(l.file()).unwrap(); - self.body.to_node(file.tree().syntax()) - } - ModuleKind::File { file_id, .. } => files.get(file_id).unwrap().tree().syntax().clone(), - } - } -} - -fn print_tree(name: &str, children: Rc>>, level: u32) { - const INDENT_STR: &str = " "; - - for _ in 0..level { - print!("{}", INDENT_STR); - } - print!("{name}\n"); - - // for (name, module) in children.iter() { - // ; - // } - children - .iter() - .for_each(|(name, m)| print_tree(name, m.children.clone(), level + 1)) -} - -#[derive(Debug)] -enum ModuleKind { - Inline(Loc), - File { - declaration: Loc, - file_id: PathBuf, - }, -} diff --git a/crates/lang/src/ast/namespace.rs b/crates/lang/src/ast/namespace.rs deleted file mode 100644 index 014a6c8..0000000 --- a/crates/lang/src/ast/namespace.rs +++ /dev/null @@ -1,103 +0,0 @@ -use std::{ - cell::RefCell, - collections::{HashMap, HashSet}, - rc::Rc, -}; - -use super::{ - mod_tree::Module, - nodes, - path::{ItemPath, OwnedItemPath}, -}; - -// requires mappings: -// names -> sets of references to individual objects -// paths -> individual objects -// glob paths -> sets of object refs -// (OPT/LATER) names (fuzzy) ~> sets of objects -#[derive(Debug)] -pub struct Registry { - defs: Vec>, - mods: Vec>, - names: HashMap>, - paths: HashMap, -} - -impl Registry { - pub fn new() -> Self { - Self { - defs: Vec::new(), - mods: Vec::new(), - names: HashMap::new(), - paths: HashMap::new(), - } - } - - // TODO: rewrite. has lots of flaws - pub fn insert_mod(&mut self, path: ItemPath<'_>, module: Rc) -> Option { - let idx = self.mods.len(); - let Some(name) = path.name() else { return None }; - self.mods.push(StoreObj::new(&name, Mod { module })); - - if let Some(set) = self.names.get_mut(&name) { - set.insert(RegistryIdx::Mod(idx)); - } else { - self.names - .insert(name, HashSet::from([RegistryIdx::Mod(idx)])); - } - - if self - .paths - .get(&path.clone().into()) - .is_some_and(|other_idx| *other_idx != RegistryIdx::Mod(idx)) - { - return None; - } else { - self.paths.insert(path.into(), RegistryIdx::Mod(idx)) - } - } -} - -impl Default for Registry { - fn default() -> Self { - Self::new() - } -} - -#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)] -pub enum RegistryIdx { - Def(usize), - Mod(usize), -} - -#[derive(Debug)] -struct StoreObj { - inner: Rc>, -} - -impl StoreObj { - pub fn new(name: impl ToString, item: T) -> Self { - Self { - inner: Rc::new(InnerStoreObj { - name: name.to_string(), - obj: item, - }), - } - } -} - -#[derive(Debug)] -struct InnerStoreObj { - name: String, - obj: T, -} - -#[derive(Debug)] -struct Mod { - module: Rc, -} - -#[derive(Debug)] -struct Def { - node: nodes::Def, -} diff --git a/crates/lang/src/ast/nodes.rs b/crates/lang/src/ast/nodes.rs deleted file mode 100644 index 744596e..0000000 --- a/crates/lang/src/ast/nodes.rs +++ /dev/null @@ -1,77 +0,0 @@ -use crate::lst_parser::syntax_kind::SyntaxKind::*; -use crate::SyntaxNode; -use rowan::Language; -macro_rules! ast_nodes { - ($($ast:ident, $kind:ident);+) => { - $( - #[derive(Debug, PartialEq, Eq, Hash)] - #[repr(transparent)] - pub struct $ast(SyntaxNode); - impl rowan::ast::AstNode for $ast { - type Language = crate::Lang; - - fn can_cast(kind: ::Kind) -> bool { - kind == $kind - } - - fn cast(node: SyntaxNode) -> Option { - if node.kind() == $kind { - Some(Self(node)) - } else { - None - } - } - - fn syntax(&self) -> &SyntaxNode { - &self.0 - } - } - )+ - }; -} -ast_nodes!( - Def, DEF; - DefName, DEF_NAME; - DefBody, DEF_BODY; - - Mod, MODULE; - ModName, MODULE_NAME; - ModBody, MODULE_BODY; - - Use, USE; - UsePat, USE_PAT; - PatItem, PAT_ITEM; - PatGlob, PAT_GLOB; - PatGroup, PAT_GROUP; - - Literal, LITERAL; - IntLit, INT_NUM; - FloatLit, FLOAT_NUM; - StringLit, STRING; - - Matrix, MATRIX; - MatrixRow, MAT_ROW; - Vector, VEC; - List, LIST; - CollectionItem, COLLECTION_ITEM; - - ParenthesizedExpr, PARENTHESIZED_EXPR; - Expression, EXPR; - - Pipeline, PIPELINE; - - Instruction, INSTR; - InstructionName, INSTR_NAME; - InstructionParams, INSTR_PARAMS; - - AttributeSet, ATTR_SET; - Attribute, ATTR; - AttributeName, ATTR_NAME; - AttributeValue, ATTR_VALUE; - - ParseError, PARSE_ERR; - LexError, LEX_ERR; - - Root, ROOT; - Eof, EOF -); diff --git a/crates/lang/src/ast/path.rs b/crates/lang/src/ast/path.rs deleted file mode 100644 index a15f141..0000000 --- a/crates/lang/src/ast/path.rs +++ /dev/null @@ -1,94 +0,0 @@ -use std::borrow::Cow; - -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct ItemPath<'a> { - items: Vec>, -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct OwnedItemPath { - items: Vec, -} - -impl OwnedItemPath { - pub fn name(&self) -> Option { - self.items.last().cloned() - } -} - -impl From> for OwnedItemPath { - fn from(value: ItemPath<'_>) -> Self { - Self { - items: value - .items - .into_iter() - .map(|v| v.into_owned()) - .collect::>(), - } - } -} - -impl<'a> ItemPath<'a> { - pub fn new() -> Self { - Self { items: Vec::new() } - } - - pub fn from_slices(slice: &[&'a str]) -> Self { - Self { - items: slice.into_iter().map(|i| (*i).into()).collect::>(), - } - } - - pub fn push(mut self, item: impl Into>) -> Self { - self.items.push(item.into()); - self - } - - pub fn name(&self) -> Option { - self.items.last().cloned().map(|item| item.into_owned()) - } -} - -impl<'a> TryFrom> for ItemPath<'a> { - type Error = (); - - fn try_from(value: Pattern<'a>) -> Result { - let mut items = Vec::new(); - - for i in value.items { - match i { - PatternEl::Name(n) => items.push(n), - PatternEl::Glob => return Err(()), - } - } - - Ok(Self { items }) - } -} - -#[derive(Clone, Debug)] -pub struct Pattern<'a> { - items: Vec>, -} - -impl<'a> Pattern<'a> { - pub fn new() -> Self { - Self { items: Vec::new() } - } - - pub fn add_name(mut self, name: &'a str) -> Self { - self.items.push(PatternEl::Name(name.into())); - self - } - - pub fn add_glob(mut self) -> Self { - self.items.push(PatternEl::Glob); - self - } -} - -#[derive(Clone, Debug)] -enum PatternEl<'a> { - Name(Cow<'a, str>), - Glob, -} diff --git a/crates/lang/src/ast/source_file.rs b/crates/lang/src/ast/source_file.rs deleted file mode 100644 index 912decd..0000000 --- a/crates/lang/src/ast/source_file.rs +++ /dev/null @@ -1,81 +0,0 @@ -use std::path::{Path, PathBuf}; - -use rowan::ast::{AstNode, AstPtr}; - -use crate::lst_parser::{ - grammar::source_file, - input::Input, - output::Output, - syntax_kind::{self, SyntaxKind}, - Parser, -}; - -use super::{ - error::Error, - nodes::{Def, Mod, Root, Use}, -}; - -#[derive(Debug)] -pub struct SourceFile { - lst: Root, - modules: Vec>, - defs: Vec>, - uses: Vec>, -} - -impl SourceFile { - pub fn parse_from(path: &Path, source_text: String) -> (Self, Vec) { - let toks = syntax_kind::lex(&source_text); - let input = Input::new(&toks); - let mut parser = Parser::new(input); - - source_file(&mut parser); - - let parser_out = parser.finish(); - let out = Output::from_parser_output(toks, parser_out); - - let lst = out.syntax(); - - let mut modules = Vec::new(); - let mut defs = Vec::new(); - let mut uses = Vec::new(); - - for c in lst.children() { - match c.kind() { - SyntaxKind::MODULE => modules.push(AstPtr::new(&Mod::cast(c).unwrap())), - SyntaxKind::DEF => defs.push(AstPtr::new(&Def::cast(c).unwrap())), - SyntaxKind::USE => uses.push(AstPtr::new(&Use::cast(c).unwrap())), - _ => {} - } - } - - ( - Self { - lst: Root::cast(lst).unwrap(), - modules, - defs, - uses, - }, - out.errors() - .into_iter() - .map(|err| Error::from_syntax(path.to_owned(), err)) - .collect(), - ) - } - - pub fn tree(&self) -> &Root { - &self.lst - } - - pub fn top_level_modules(&self) -> Vec> { - self.modules.clone() - } - - pub fn top_level_defs(&self) -> Vec> { - self.defs.clone() - } - - pub fn top_level_uses(&self) -> Vec> { - self.uses.clone() - } -} diff --git a/crates/lang/src/lib.rs b/crates/lang/src/lib.rs index f48385e..a45e202 100644 --- a/crates/lang/src/lib.rs +++ b/crates/lang/src/lib.rs @@ -2,9 +2,7 @@ use crate::lst_parser::syntax_kind::SyntaxKind; -pub mod ast; pub mod lst_parser; -pub mod world; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Lang {} diff --git a/crates/lang/src/main.rs b/crates/lang/src/main.rs index c0c04d5..e9c0257 100644 --- a/crates/lang/src/main.rs +++ b/crates/lang/src/main.rs @@ -1,10 +1,7 @@ use clap::Parser; use std::{fs, path::PathBuf}; -use lang::{ - ast::World, - lst_parser::{self, grammar, input, output::Output, syntax_kind}, -}; +use lang::lst_parser::{self, grammar, input, output::Output, syntax_kind}; #[derive(Parser)] struct Args { diff --git a/crates/lang/src/world.rs b/crates/lang/src/world.rs deleted file mode 100644 index 2f32cab..0000000 --- a/crates/lang/src/world.rs +++ /dev/null @@ -1,55 +0,0 @@ -use std::{ - fmt::Display, - path::{Path, PathBuf}, - sync::{Arc, Mutex}, -}; - -use crate::world::world_creation_pool::WorldCreationPool; - -use easy_parallel::Parallel; -use futures_lite::future; -use smol::{ - channel::{unbounded, Sender}, - Executor, -}; - -use self::{error::Error, files::Files, registry::Registry}; - -pub mod error; -pub mod files; -pub mod modules; -pub mod nodes; -pub mod registry; -mod world_creation_pool; - -pub struct World {} - -impl World { - pub fn new(entry_point: &Path) -> Result { - let files = Files::new(); - let reg = Registry::new(); - - let (entry_point_id, errors) = files.add_and_parse(entry_point).map_err(|e| { - WorldCreationError::FailedToOpenEntryPoint(entry_point.to_path_buf(), e) - })?; - - let pool = WorldCreationPool::new(files, reg); - - todo!() - } -} - -#[derive(Debug)] -pub enum WorldCreationError { - FailedToOpenEntryPoint(PathBuf, std::io::Error), -} - -impl Display for WorldCreationError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - WorldCreationError::FailedToOpenEntryPoint(entry_path, e) => { - write!(f, "failed to open entry_point '{entry_path:?}': {e}") - } - } - } -} diff --git a/crates/lang/src/world/error.rs b/crates/lang/src/world/error.rs deleted file mode 100644 index 6232a68..0000000 --- a/crates/lang/src/world/error.rs +++ /dev/null @@ -1,17 +0,0 @@ -use std::path::PathBuf; - -use crate::lst_parser::error::SyntaxError; - -use super::files::FileId; - -#[derive(Debug)] -pub enum Error { - Syntax(FileId, SyntaxError), - FailedToOpenFileMod(PathBuf, std::io::Error), -} - -impl Error { - pub fn from_syntax(file: FileId, e: SyntaxError) -> Self { - Self::Syntax(file, e) - } -} diff --git a/crates/lang/src/world/files.rs b/crates/lang/src/world/files.rs deleted file mode 100644 index b4a1309..0000000 --- a/crates/lang/src/world/files.rs +++ /dev/null @@ -1,131 +0,0 @@ -use std::{ - clone, fs, - path::{Path, PathBuf}, - sync::{Arc, Mutex, RwLock}, -}; - -use dashmap::DashMap; -use rowan::ast::{AstNode, AstPtr}; - -use crate::{ - lst_parser::{ - error::SyntaxError, grammar::source_file, input::Input, output::Output, syntax_kind, Parser, - }, - Lang, -}; - -use super::{error::Error, modules::Module, nodes}; - -#[derive(Clone)] -pub struct Loc> { - file: FileId, - syntax: AstPtr, -} - -impl> Loc { - pub fn new(node: N, file: FileId) -> Self { - Self { - file, - syntax: AstPtr::new(&node), - } - } - - pub fn file(&self) -> FileId { - self.file - } - - pub fn syntax(&self) -> AstPtr { - self.syntax.clone() - } -} - -/// global file store -/// contains all known files etc. -#[derive(Clone)] -pub struct Files { - paths: Arc>>, - store: Arc>>, -} - -impl Files { - pub fn new() -> Self { - Self { - paths: Arc::new(Mutex::new(Vec::new())), - store: Arc::new(DashMap::new()), - } - } - - pub fn add_and_parse(&self, path: &Path) -> Result<(FileId, Vec), std::io::Error> { - let (file, errors) = SourceFile::read_and_parse(&path)?; - - // add file to paths and unlock again - let id = { - let path = path.clone(); - let mut paths = self.paths.lock().unwrap(); - let r = paths.len(); - paths.push(path.to_path_buf()); - FileId(r) - }; - - let _ = self.store.insert(path.to_path_buf(), Arc::new(file)); - - Ok(( - id, - errors - .into_iter() - .map(|e| Error::from_syntax(id, e)) - .collect(), - )) - } - - pub fn get(&self, id: FileId) -> Arc { - let path = { - let paths = self.paths.lock().unwrap(); - paths[id.0].clone() - }; - - self.store.get(&path).unwrap().clone() - } - - pub fn get_path(&self, id: FileId) -> PathBuf { - let paths = self.paths.lock().unwrap(); - paths[id.0].clone() - } - - pub fn path_store(&self) -> Arc>> { - self.paths.clone() - } -} - -pub struct SourceFile { - pub lst: RwLock, - root_module: Option>, -} - -impl SourceFile { - fn read_and_parse(path: &Path) -> Result<(Self, Vec), std::io::Error> { - let source_text = fs::read_to_string(&path)?; - - let toks = syntax_kind::lex(&source_text); - let input = Input::new(&toks); - let mut parser = Parser::new(input); - - source_file(&mut parser); - - let events = parser.finish(); - let out = Output::from_parser_output(toks, events); - // let lst = out.syntax(); - let (lst, errors) = out.dissolve(); - - Ok(( - Self { - lst: RwLock::new(lst), - root_module: None, - }, - errors, - )) - } -} - -#[derive(Debug, Clone, Copy)] -pub struct FileId(pub usize); diff --git a/crates/lang/src/world/modules.rs b/crates/lang/src/world/modules.rs deleted file mode 100644 index 676553b..0000000 --- a/crates/lang/src/world/modules.rs +++ /dev/null @@ -1,175 +0,0 @@ -use std::{ - string::String, - sync::{Arc, Mutex}, -}; - -use dashmap::{DashMap, DashSet}; -use rowan::ast::{AstNode, AstPtr}; - -use crate::SyntaxNode; - -use super::{ - files::{FileId, Loc}, - nodes, - registry::ItemPath, - world_creation_pool::{wait_blocker::WaitBlocker, Task, WorkerCtx}, -}; - -pub struct Module { - /// is none if this is the root module of the entry point file - decl: Option>, - body: ModuleBody, - own_path: ItemPath, - child_modules: Arc>>, - child_defs: Arc>, -} - -impl Module { - pub fn parse_mod_body( - ctx: &WorkerCtx, - tree: SyntaxNode, - path: ItemPath, - file: FileId, - ) -> (DashMap>>>>, Vec) { - let children: Vec<(String, Arc>>>, nodes::Mod)> = tree - .children() - .filter_map(|c| nodes::Mod::cast(c)) - .map(|m| { - let name = nodes::ModName::cast(m.syntax().first_child().unwrap()) - .expect("ModName should always be first child of Mod"); - ( - name.syntax().text().to_string(), - Arc::new(Mutex::new(None)), - m, - ) - }) - .collect(); - let retv: DashMap>>>> = children - .iter() - .map(|(name, mod_r, _)| (name.to_owned(), mod_r.clone())) - .collect(); - let tasks = children - .into_iter() - .map(|(name, mod_r, loc)| { - let mut path = path.clone(); - path.push(name); - Task::ParseMod(Loc::new(loc, file), mod_r, path) - }) - .collect::>(); - - (retv, tasks) - } - pub fn parse_file0( - ctx: &mut WorkerCtx, - file: FileId, - path: ItemPath, - decl: Option>, - ) { - let tree = ctx.get_tree(file); - - let (retv, tasks) = Self::parse_mod_body(ctx, tree, path.clone(), file); - - ctx.send_tasks( - Task::ParseFileMod1 { - file, - decl, - ret: retv.into(), - path, - }, - tasks, - ) - } - - pub fn parse_mod( - ctx: &mut WorkerCtx, - loc: Loc, - path: ItemPath, - ret: Arc>>, - blocker: WaitBlocker, - ) { - let mod_decl = ctx.resolve_loc(loc); - let children = mod_decl.syntax().children().collect::>(); - - if children.len() == 1 { - // TODO: file mod - todo!() - } else if children.len() == 2 { - // inline mod - } - } - - pub fn parse_inline_mod( - ctx: &mut WorkerCtx, - decl: Loc, - path: ItemPath, - ret: Arc>>>, - blocker: WaitBlocker, - ) { - let mod_decl_children = ctx - .resolve_loc(decl.clone()) - .syntax() - .children() - .collect::>(); - - assert_eq!(mod_decl_children.len(), 2); - - let name = nodes::ModName::cast(mod_decl_children[0].clone()).unwrap(); - let body = nodes::ModBody::cast(mod_decl_children[1].clone()).unwrap(); - - let (retv, tasks) = - Self::parse_mod_body(ctx, body.syntax().clone(), path.clone(), decl.file()); - - ctx.send_tasks( - Task::CompleteMod { - ret_self: ret, - body: ModuleBody::Inline(Loc::new(body, decl.file())), - decl: Some(decl), - path, - child_mods: retv.into(), - blocker, - }, - tasks, - ) - } - - pub fn complete_mod( - ctx: &mut WorkerCtx, - decl: Option>, - ret_self: Arc>>>, - body: ModuleBody, - path: ItemPath, - child_mods: Arc>>>>>, - blocker: WaitBlocker, - ) { - assert!(child_mods - .iter() - .all(|item| item.value().lock().unwrap().is_some())); - - let module = Arc::new(Module { - decl, - body, - own_path: path, - child_modules: Arc::new( - Arc::<_>::unwrap_or_clone(child_mods) - .into_iter() - .map(|(name, module)| { - let module = module.lock().unwrap().take().unwrap(); - (name, module) - }) - .collect(), - ), - child_defs: Arc::default(), - }); - - let mut ret_self = ret_self.lock().unwrap(); - *ret_self = Some(module); - drop(blocker); - } -} - -struct Def; - -pub enum ModuleBody { - Inline(Loc), - File(FileId), -} diff --git a/crates/lang/src/world/nodes.rs b/crates/lang/src/world/nodes.rs deleted file mode 100644 index 303a3a1..0000000 --- a/crates/lang/src/world/nodes.rs +++ /dev/null @@ -1,77 +0,0 @@ -use crate::lst_parser::syntax_kind::SyntaxKind::*; -use crate::SyntaxNode; -use rowan::Language; -macro_rules! ast_nodes { -($($ast:ident, $kind:ident);+) => { - $( - #[derive(Debug, Clone, PartialEq, Eq, Hash)] - #[repr(transparent)] - pub struct $ast(SyntaxNode); - impl rowan::ast::AstNode for $ast { - type Language = crate::Lang; - - fn can_cast(kind: ::Kind) -> bool { - kind == $kind - } - - fn cast(node: SyntaxNode) -> Option { - if node.kind() == $kind { - Some(Self(node)) - } else { - None - } - } - - fn syntax(&self) -> &SyntaxNode { - &self.0 - } - } - )+ -}; -} -ast_nodes!( - Def, DEF; - DefName, DEF_NAME; - DefBody, DEF_BODY; - - Mod, MODULE; - ModName, MODULE_NAME; - ModBody, MODULE_BODY; - - Use, USE; - UsePat, USE_PAT; - PatItem, PAT_ITEM; - PatGlob, PAT_GLOB; - PatGroup, PAT_GROUP; - - Literal, LITERAL; - IntLit, INT_NUM; - FloatLit, FLOAT_NUM; - StringLit, STRING; - - Matrix, MATRIX; - MatrixRow, MAT_ROW; - Vector, VEC; - List, LIST; - CollectionItem, COLLECTION_ITEM; - - ParenthesizedExpr, PARENTHESIZED_EXPR; - Expression, EXPR; - - Pipeline, PIPELINE; - - Instruction, INSTR; - InstructionName, INSTR_NAME; - InstructionParams, INSTR_PARAMS; - - AttributeSet, ATTR_SET; - Attribute, ATTR; - AttributeName, ATTR_NAME; - AttributeValue, ATTR_VALUE; - - ParseError, PARSE_ERR; - LexError, LEX_ERR; - - Root, ROOT; - Eof, EOF -); diff --git a/crates/lang/src/world/registry.rs b/crates/lang/src/world/registry.rs deleted file mode 100644 index 791be15..0000000 --- a/crates/lang/src/world/registry.rs +++ /dev/null @@ -1,41 +0,0 @@ -use std::sync::{Arc, Mutex, RwLock}; - -use dashmap::{DashMap, DashSet}; - -use super::modules::Module; - -pub type ItemPath = Vec; - -#[derive(Clone)] -pub struct Registry(Arc); - -impl Registry { - pub fn new() -> Self { - Self(Arc::new(RegistryInner::new())) - } -} - -struct RegistryInner { - /// ids will refer to paths of modules - paths: RwLock>, - modules: DashMap>, - names: DashMap>, -} - -impl RegistryInner { - fn new() -> Self { - Self { - paths: RwLock::new(Vec::new()), - modules: DashMap::new(), - names: DashMap::new(), - } - } -} - -pub enum RegistryId { - /// refer to the modlue item itself, the name must be the same as the last item of the path - Module(usize), - /// refer to a def in a module - /// name must refer to name of child of module - Def(usize), -} diff --git a/crates/lang/src/world/world_creation_pool.rs b/crates/lang/src/world/world_creation_pool.rs deleted file mode 100644 index 651d7eb..0000000 --- a/crates/lang/src/world/world_creation_pool.rs +++ /dev/null @@ -1,215 +0,0 @@ -use std::{ - collections::HashMap, - path::PathBuf, - sync::{Arc, Mutex}, - thread, -}; - -use crossbeam::channel::{Receiver, Sender}; -use dashmap::DashMap; -use rowan::ast::{AstNode, AstPtr}; - -use crate::{Lang, SyntaxNode}; - -use self::wait_blocker::WaitBlocker; - -use super::{ - error::Error, - files::{FileId, Files, Loc}, - modules::{Module, ModuleBody}, - nodes, - registry::{ItemPath, Registry}, -}; - -pub mod wait_blocker; - -pub(super) struct WorldCreationPool { - workers: Vec, - tx: Sender, -} - -impl WorldCreationPool { - pub fn new(files: Files, reg: Registry) -> Self { - let mut workers = Vec::new(); - let (tx, rx) = crossbeam::channel::unbounded(); - - for i in 0..num_cpus::get() { - workers.push(Worker::new( - i, - files.clone(), - reg.clone(), - tx.clone(), - rx.clone(), - )) - } - - Self { workers, tx } - } -} - -enum Job { - WaitingFor(WaitBlocker, Task), - Awaited(WaitBlocker, Task), -} - -pub enum Task { - ParseMod(Loc, Arc>>>, ItemPath), - ParseFileMod0 { - file: FileId, - decl: Option>, - path: ItemPath, - }, - ParseFileMod1 { - file: FileId, - decl: Option>, - path: ItemPath, - ret: Arc>>>>>, - }, - CompleteMod { - ret_self: Arc>>>, - decl: Option>, - body: ModuleBody, - path: ItemPath, - child_mods: Arc>>>>>, - blocker: WaitBlocker, - }, - OpenFile(PathBuf), -} - -struct Worker { - id: usize, - // thead: thread::JoinHandle>, - thread: thread::JoinHandle<()>, -} - -pub struct WorkerCtx { - errors: Vec, - files: Files, - local_files: HashMap, - pub reg: Registry, - tx: Sender, -} - -impl WorkerCtx { - pub fn get_tree(&mut self, id: FileId) -> SyntaxNode { - let p = self.files.get_path(id); - if self.local_files.contains_key(&p) { - self.local_files[&p].clone() - } else { - let f = self.files.get(id); - let lst = SyntaxNode::new_root(f.lst.read().unwrap().clone()); - self.local_files.insert(p, lst.clone()); - lst - } - } - - pub fn resolve_loc>(&mut self, loc: Loc) -> N { - let f = self.get_tree(loc.file()); - - loc.syntax().to_node(&f) - } - - pub fn send_tasks(&self, task: Task, dependencies: Vec) { - let blocker = WaitBlocker::new(); - for dep_task in dependencies { - self.tx - .send(Job::Awaited(blocker.clone(), dep_task)) - .unwrap(); - } - self.tx.send(Job::WaitingFor(blocker, task)).unwrap(); - } -} - -impl Worker { - fn new(id: usize, files: Files, reg: Registry, sender: Sender, rx: Receiver) -> Self { - let thread_handle = thread::spawn(move || { - let ctx = WorkerCtx { - errors: Vec::new(), - local_files: HashMap::new(), - files, - reg, - tx: sender, - }; - - for job in &rx { - // if matches!(job, Job::WithCond(_, _)) { - - // } - match job { - Job::WaitingFor(blocker, task) => { - if blocker.is_ready() { - Self::do_task(&ctx, task, None) - } else if rx.is_empty() { - if let Some(blocker) = - blocker.wait_for(std::time::Duration::from_millis(50)) - { - ctx.tx.send(Job::WaitingFor(blocker, task)).unwrap(); - } else { - Self::do_task(&ctx, task, None) - } - } else { - ctx.tx.send(Job::WaitingFor(blocker, task)).unwrap(); - } - } - Job::Awaited(blocker, task) => { - Self::do_task(&ctx, task, Some(blocker.clone())); - drop(blocker) - } - } - - // if let Job::WithCond(blocker, job_inner) = job_msg { - // if blocker.is_ready() { - // job = Box::::into_inner(job_inner); - // } else if rx.is_empty() { - // if let Some(blocker) = - // blocker.wait_for(std::time::Duration::from_millis(50)) - // { - // job = Job::WithCond(blocker, job_inner); - // } else { - // job = Box::::into_inner(job_inner); - // } - // } else { - // job = Job::WithCond(blocker, job_inner); - // } - // } else { - // job = job_msg; - // } - - // match job { - // Job::ParseFileMod { file, decl } => todo!(), - // Job::OpenFile(path) => todo!(), - // Job::WithCond(blocker, job) => { - // ctx.tx.send(Job::WithCond(blocker, job)).unwrap() - // } - // } - } - }); - - Self { - id, - thread: thread_handle, - } - } - - fn do_task(ctx: &WorkerCtx, task: Task, blocker: Option) { - match task { - Task::ParseMod(_, _, _) => todo!(), - Task::ParseFileMod0 { file, decl, path } => todo!(), - Task::ParseFileMod1 { - file, - decl, - path, - ret, - } => todo!(), - Task::CompleteMod { - ret_self, - decl, - body, - path, - child_mods, - blocker, - } => todo!(), - Task::OpenFile(_) => todo!(), - } - } -} diff --git a/crates/lang/src/world/world_creation_pool/wait_blocker.rs b/crates/lang/src/world/world_creation_pool/wait_blocker.rs deleted file mode 100644 index 2d23d8a..0000000 --- a/crates/lang/src/world/world_creation_pool/wait_blocker.rs +++ /dev/null @@ -1,87 +0,0 @@ -use std::{ - sync::{Arc, Condvar, Mutex}, - time::Duration, -}; - -/// like a WaitGroup from crossbeam, but can also just check if it's the last one -pub struct WaitBlocker { - inner: Arc, -} - -struct Inner { - waiting: Mutex, - cvar: Condvar, -} - -impl WaitBlocker { - pub fn new() -> Self { - Self { - inner: Arc::new(Inner { - waiting: Mutex::new(1), - cvar: Condvar::new(), - }), - } - } - - pub fn wait(self) { - if *self.inner.waiting.lock().unwrap() == 1 { - return; - } - - let inner = self.inner.clone(); - drop(self); - - inner - .cvar - .wait_while(inner.waiting.lock().unwrap(), |w| *w > 0); - } - - pub fn wait_for(self, dur: Duration) -> Option { - if *self.inner.waiting.lock().unwrap() == 1 { - return None; - } - - let inner = self.inner.clone(); - drop(self); - - let (_, timeout_res) = inner - .cvar - .wait_timeout_while(inner.waiting.lock().unwrap(), dur, |w| *w > 0) - .unwrap(); - - if timeout_res.timed_out() { - None - } else { - { - let mut w = inner.waiting.lock().unwrap(); - *w += 1; - } - Some(Self { inner }) - } - } - - pub fn is_ready(&self) -> bool { - *self.inner.waiting.lock().unwrap() == 1 - } -} - -impl Clone for WaitBlocker { - fn clone(&self) -> Self { - let mut w = self.inner.waiting.lock().unwrap(); - *w += 1; - drop(w); - Self { - inner: self.inner.clone(), - } - } -} - -impl Drop for WaitBlocker { - fn drop(&mut self) { - let mut w = self.inner.waiting.lock().unwrap(); - *w -= 1; - if *w == 0 { - self.inner.cvar.notify_all() - } - } -}