feat(parse): run in parallel

This commit is contained in:
rvcas 2024-03-06 17:05:07 -05:00 committed by Lucas
parent 9c5556aa1e
commit f8377af0c8
2 changed files with 85 additions and 44 deletions

View File

@ -564,16 +564,21 @@ where
}
fn parse_sources(&mut self, package_name: PackageName) -> Result<ParsedModules, Vec<Error>> {
let mut errors = Vec::new();
let mut parsed_modules = HashMap::with_capacity(self.sources.len());
use rayon::prelude::*;
for Source {
let (parsed_modules, errors) = self
.sources
.par_drain(0..)
.fold(
|| (ParsedModules::new(), Vec::new()),
|(mut parsed_modules, mut errors), elem| {
let Source {
path,
name,
code,
kind,
} in self.sources.drain(0..)
{
} = elem;
match aiken_lang::parser::module(&code, kind) {
Ok((mut ast, extra)) => {
// Store the name
@ -589,35 +594,61 @@ where
package: package_name.to_string(),
};
if let Some(first) = self
.defined_modules
.insert(module.name.clone(), module.path.clone())
{
return Err(Error::DuplicateModule {
module: module.name.clone(),
first,
second: module.path,
}
.into());
}
parsed_modules.insert(module.name.clone(), module);
(parsed_modules, errors)
}
Err(errs) => {
for error in errs {
errors.push(Error::Parse {
path: path.clone(),
src: code.clone(),
named: NamedSource::new(path.display().to_string(), code.clone()),
error: Box::new(error),
errors.push((
path.clone(),
code.clone(),
NamedSource::new(path.display().to_string(), code.clone()),
Box::new(error),
))
}
(parsed_modules, errors)
}
}
},
)
.reduce(
|| (ParsedModules::new(), Vec::new()),
|(mut parsed_modules, mut errors), (mut parsed, errs)| {
parsed_modules.extend(parsed.drain());
errors.extend(errs);
(parsed_modules, errors)
},
);
let mut errors: Vec<Error> = errors
.into_iter()
.map(|(path, src, named, error)| Error::Parse {
path,
src,
named,
error,
})
}
}
.collect();
for parsed_module in parsed_modules.values() {
if let Some(first) = self
.defined_modules
.insert(parsed_module.name.clone(), parsed_module.path.clone())
{
errors.push(Error::DuplicateModule {
module: parsed_module.name.clone(),
first,
second: parsed_module.path.clone(),
});
}
}
if errors.is_empty() {
Ok(parsed_modules.into())
Ok(parsed_modules)
} else {
Err(errors)
}

View File

@ -42,6 +42,10 @@ impl ParsedModule {
pub struct ParsedModules(HashMap<String, ParsedModule>);
impl ParsedModules {
pub fn new() -> Self {
Self(HashMap::new())
}
pub fn sequence(&self) -> Result<Vec<String>, Error> {
let inputs = self
.0
@ -103,6 +107,12 @@ impl ParsedModules {
}
}
impl Default for ParsedModules {
fn default() -> Self {
Self::new()
}
}
impl From<HashMap<String, ParsedModule>> for ParsedModules {
fn from(parsed_modules: HashMap<String, ParsedModule>) -> Self {
ParsedModules(parsed_modules)