Rule execution now runs, no tests tho

This commit is contained in:
2022-08-19 12:55:02 +02:00
parent 329dea72b7
commit 891d78c112
30 changed files with 925 additions and 560 deletions

View File

@@ -1,10 +1,13 @@
use std::cell::RefCell;
use std::collections::{HashMap, HashSet, VecDeque};
use std::fmt::Debug;
use std::rc::Rc;
use mappable_rc::Mrc;
use crate::expression::Rule;
use crate::parse::{self, FileEntry};
use crate::utils::Cache;
use crate::utils::{Cache, mrc_derive, to_mrc_slice};
use super::name_resolver::NameResolver;
use super::module_error::ModuleError;
@@ -17,27 +20,29 @@ type ParseResult<T, ELoad> = Result<T, ModuleError<ELoad>>;
pub struct Module {
pub rules: Vec<Rule>,
pub exports: Vec<String>,
pub references: Vec<Vec<String>>
pub references: Vec<Mrc<[String]>>
}
pub type RuleCollectionResult<ELoad> = Result<Vec<super::Rule>, ModuleError<ELoad>>;
pub fn rule_collector<F: 'static, ELoad>(
mut load_mod: F,
prelude: Vec<String>
// ) -> impl FnMut(Vec<String>) -> Result<&'a Vec<super::Rule>, ParseError<ELoad>> + 'a
) -> Cache<'static, Vec<String>, Result<Vec<super::Rule>, ModuleError<ELoad>>>
) -> Cache<'static, Mrc<[String]>, RuleCollectionResult<ELoad>>
where
F: FnMut(Vec<String>) -> Result<Loaded, ELoad>,
F: FnMut(Mrc<[String]>) -> Result<Loaded, ELoad>,
ELoad: Clone + Debug
{
let load_mod_rc = RefCell::new(load_mod);
// Map paths to a namespace with name list (folder) or module with source text (file)
let loaded = Rc::new(Cache::new(move |path: Vec<String>, _|
let loaded = Rc::new(Cache::new(move |path: Mrc<[String]>, _|
-> ParseResult<Loaded, ELoad> {
load_mod(path).map_err(ModuleError::Load)
(load_mod_rc.borrow_mut())(path).map_err(ModuleError::Load)
}));
// Map names to the longest prefix that points to a valid module
let modname = Rc::new(Cache::new({
let loaded = Rc::clone(&loaded);
move |symbol: Vec<String>, _| -> Result<Vec<String>, Vec<ModuleError<ELoad>>> {
move |symbol: Mrc<[String]>, _| -> Result<Mrc<[String]>, Vec<ModuleError<ELoad>>> {
let mut errv: Vec<ModuleError<ELoad>> = Vec::new();
let reg_err = |e, errv: &mut Vec<ModuleError<ELoad>>| {
errv.push(e);
@@ -45,11 +50,10 @@ where
else { Ok(()) }
};
loop {
let (path, _) = symbol.split_at(symbol.len() - errv.len());
let pathv = path.to_vec();
match loaded.try_find(&pathv) {
let path = mrc_derive(&symbol, |s| &s[..s.len() - errv.len()]);
match loaded.try_find(&path) {
Ok(imports) => match imports.as_ref() {
Loaded::Module(_) => break Ok(pathv.clone()),
Loaded::Module(_) => break Ok(path),
_ => reg_err(ModuleError::None, &mut errv)?
},
Err(err) => reg_err(err, &mut errv)?
@@ -61,7 +65,7 @@ where
let preparsed = Rc::new(Cache::new({
let loaded = Rc::clone(&loaded);
let prelude2 = prelude.clone();
move |path: Vec<String>, _| -> ParseResult<Vec<FileEntry>, ELoad> {
move |path: Mrc<[String]>, _| -> ParseResult<Vec<FileEntry>, ELoad> {
let loaded = loaded.try_find(&path)?;
if let Loaded::Module(source) = loaded.as_ref() {
Ok(parse::parse(&prelude2, source.as_str())?)
@@ -72,7 +76,7 @@ where
let exports = Rc::new(Cache::new({
let loaded = Rc::clone(&loaded);
let preparsed = Rc::clone(&preparsed);
move |path: Vec<String>, _| -> ParseResult<Vec<String>, ELoad> {
move |path: Mrc<[String]>, _| -> ParseResult<Vec<String>, ELoad> {
let loaded = loaded.try_find(&path)?;
if let Loaded::Namespace(names) = loaded.as_ref() {
return Ok(names.clone());
@@ -88,19 +92,19 @@ where
let imports = Rc::new(Cache::new({
let preparsed = Rc::clone(&preparsed);
let exports = Rc::clone(&exports);
move |path: Vec<String>, _| -> ParseResult<HashMap<String, Vec<String>>, ELoad> {
let entv = preparsed.try_find(&path)?.clone();
move |path: Mrc<[String]>, _| -> ParseResult<HashMap<String, Mrc<[String]>>, ELoad> {
let entv = preparsed.try_find(&path)?;
let import_entries = parse::imports(entv.iter());
let mut imported_symbols: HashMap<String, Vec<String>> = HashMap::new();
let mut imported_symbols: HashMap<String, Mrc<[String]>> = HashMap::new();
for imp in import_entries {
let export = exports.try_find(&imp.path)?;
if let Some(ref name) = imp.name {
if export.contains(&name) {
imported_symbols.insert(name.clone(), imp.path.clone());
if export.contains(name) {
imported_symbols.insert(name.clone(), Mrc::clone(&imp.path));
}
} else {
for exp in export.as_ref() {
imported_symbols.insert(exp.clone(), imp.path.clone());
imported_symbols.insert(exp.clone(), Mrc::clone(&imp.path));
}
}
}
@@ -112,7 +116,7 @@ where
let preparsed = Rc::clone(&preparsed);
let imports = Rc::clone(&imports);
let loaded = Rc::clone(&loaded);
move |path: Vec<String>, _| -> ParseResult<Vec<FileEntry>, ELoad> {
move |path: Mrc<[String]>, _| -> ParseResult<Vec<FileEntry>, ELoad> {
let imported_ops: Vec<String> =
imports.try_find(&path)?
.keys()
@@ -127,45 +131,44 @@ where
} else { Err(ModuleError::None) }
}
}));
let mut name_resolver = NameResolver::new({
let mut name_resolver_rc = RefCell::new(NameResolver::new({
let modname = Rc::clone(&modname);
move |path| {
Some(modname.try_find(path).ok()?.as_ref().clone())
Some(modname.try_find(&path).ok()?.as_ref().clone())
}
}, {
let imports = Rc::clone(&imports);
move |path| {
imports.try_find(path).map(|f| f.as_ref().clone())
imports.try_find(&path).map(|f| f.as_ref().clone())
}
});
}));
// Turn parsed files into a bag of rules and a list of toplevel export names
let resolved = Rc::new(Cache::new({
let parsed = Rc::clone(&parsed);
let exports = Rc::clone(&exports);
let imports = Rc::clone(&imports);
let modname = Rc::clone(&modname);
move |path: Vec<String>, _| -> ParseResult<Module, ELoad> {
move |path: Mrc<[String]>, _| -> ParseResult<Module, ELoad> {
let mut name_resolver = name_resolver_rc.borrow_mut();
let module = Module {
rules: parsed.try_find(&path)?
.iter()
.filter_map(|ent| {
if let FileEntry::Rule(Rule{source, prio, target}, _) = ent {
Some(Rule {
source: source.iter().map(|ex| prefix_expr(ex, &path)).collect(),
target: target.iter().map(|ex| prefix_expr(ex, &path)).collect(),
source: source.iter().map(|ex| prefix_expr(ex, Mrc::clone(&path))).collect(),
target: target.iter().map(|ex| prefix_expr(ex, Mrc::clone(&path))).collect(),
prio: *prio,
})
} else { None }
})
.map(|rule| Ok(super::Rule {
source: rule.source.iter()
source: to_mrc_slice(rule.source.iter()
.map(|ex| name_resolver.process_expression(ex))
.collect::<Result<Vec<_>, _>>()?,
target: rule.target.iter()
.collect::<Result<Vec<_>, _>>()?),
target: to_mrc_slice(rule.target.iter()
.map(|ex| name_resolver.process_expression(ex))
.collect::<Result<Vec<_>, _>>()?,
// source: name_resolver.process_expression(&rule.source)?,
// target: name_resolver.process_expression(&rule.target)?,
.collect::<Result<Vec<_>, _>>()?),
..rule
}))
.collect::<ParseResult<Vec<super::Rule>, ELoad>>()?,
@@ -173,19 +176,20 @@ where
references: imports.try_find(&path)?
.values()
.filter_map(|imps| {
modname.try_find(&imps).ok().map(|r| r.as_ref().clone())
modname.try_find(imps).ok().map(|r| r.as_ref().clone())
})
.collect()
};
Ok(module)
}
}));
let all_rules = Cache::new({
Cache::new({
let resolved = Rc::clone(&resolved);
move |path: Vec<String>, _| -> ParseResult<Vec<super::Rule>, ELoad> {
let mut processed: HashSet<Vec<String>> = HashSet::new();
move |path: Mrc<[String]>, _| -> ParseResult<Vec<super::Rule>, ELoad> {
// Breadth-first search
let mut processed: HashSet<Mrc<[String]>> = HashSet::new();
let mut rules: Vec<super::Rule> = Vec::new();
let mut pending: VecDeque<Vec<String>> = VecDeque::new();
let mut pending: VecDeque<Mrc<[String]>> = VecDeque::new();
pending.push_back(path);
while let Some(el) = pending.pop_front() {
let resolved = resolved.try_find(&el)?;
@@ -201,6 +205,5 @@ where
};
Ok(rules)
}
});
return all_rules;
})
}