Most files suffered major changes

- Less ambiguous syntax
- Better parser (Chumsky only does tokenization now)
- Tidy(|ier) error handling
- Facade for simplified embedding
- External code grouped in (fairly) self-contained Systems
- Dynamic action dispatch
- Many STL additions
This commit is contained in:
2023-08-17 20:47:08 +01:00
parent 751a02a1ec
commit 3fdabc29da
139 changed files with 4269 additions and 1783 deletions

View File

@@ -1,9 +1,7 @@
use std::rc::Rc;
use super::alias_map::AliasMap;
use super::decls::UpdatedFn;
use crate::interner::{Interner, Tok};
use crate::pipeline::error::{NotExported, NotFound, ProjectError};
use crate::error::{NotExported, NotFound, ProjectError, ProjectResult};
use crate::interner::Tok;
use crate::pipeline::project_tree::split_path;
use crate::representations::project::{ProjectModule, ProjectTree};
use crate::representations::tree::{ModMember, WalkErrorKind};
@@ -15,8 +13,7 @@ fn assert_visible(
source: &[Tok<String>], // must point to a file or submodule
target: &[Tok<String>], // may point to a symbol or module of any kind
project: &ProjectTree<VName>,
i: &Interner,
) -> Result<(), Rc<dyn ProjectError>> {
) -> ProjectResult<()> {
let (tgt_item, tgt_path) = unwrap_or!(target.split_last(); return Ok(()));
let shared_len =
source.iter().zip(tgt_path.iter()).take_while(|(a, b)| a == b).count();
@@ -27,11 +24,11 @@ fn assert_visible(
WalkErrorKind::Private =>
unreachable!("visibility is not being checked here"),
WalkErrorKind::Missing => NotFound::from_walk_error(
source,
&[],
&tgt_path[..vis_ignored_len],
&project.0,
e,
i,
)
.rc(),
})?;
@@ -39,37 +36,51 @@ fn assert_visible(
.walk_ref(&tgt_path[vis_ignored_len..], true)
.map_err(|e| match e.kind {
WalkErrorKind::Missing => NotFound::from_walk_error(
source,
&tgt_path[..vis_ignored_len],
&tgt_path[vis_ignored_len..],
&project.0,
e,
i,
)
.rc(),
WalkErrorKind::Private => {
let full_path = &tgt_path[..shared_len + e.pos];
let (file, sub) = split_path(full_path, project);
let (ref_file, ref_sub) = split_path(source, project);
NotExported {
file: i.extern_all(file),
subpath: i.extern_all(sub),
referrer_file: i.extern_all(ref_file),
referrer_subpath: i.extern_all(ref_sub),
// These errors are encountered during error reporting but they're more
// fundamental / higher prio than the error to be raised and would
// emerge nonetheless so they take over and the original error is
// swallowed
match split_path(full_path, project) {
Err(e) =>
NotFound::from_walk_error(source, &[], full_path, &project.0, e)
.rc(),
Ok((file, sub)) => {
let (ref_file, ref_sub) = split_path(source, project)
.expect("Source path assumed to be valid");
NotExported {
file: file.to_vec(),
subpath: sub.to_vec(),
referrer_file: ref_file.to_vec(),
referrer_subpath: ref_sub.to_vec(),
}
.rc()
},
}
.rc()
},
})?;
let tgt_item_exported = direct_parent.extra.exports.contains_key(tgt_item);
let target_prefixes_source = shared_len == tgt_path.len();
if !tgt_item_exported && !target_prefixes_source {
let (file, sub) = split_path(target, project);
let (ref_file, ref_sub) = split_path(source, project);
let (file, sub) = split_path(target, project).map_err(|e| {
NotFound::from_walk_error(source, &[], target, &project.0, e).rc()
})?;
let (ref_file, ref_sub) = split_path(source, project)
.expect("The source path is assumed to be valid");
Err(
NotExported {
file: i.extern_all(file),
subpath: i.extern_all(sub),
referrer_file: i.extern_all(ref_file),
referrer_subpath: i.extern_all(ref_sub),
file: file.to_vec(),
subpath: sub.to_vec(),
referrer_file: ref_file.to_vec(),
referrer_subpath: ref_sub.to_vec(),
}
.rc(),
)
@@ -84,9 +95,8 @@ fn collect_aliases_rec(
module: &ProjectModule<VName>,
project: &ProjectTree<VName>,
alias_map: &mut AliasMap,
i: &Interner,
updated: &impl UpdatedFn,
) -> Result<(), Rc<dyn ProjectError>> {
) -> ProjectResult<()> {
// Assume injected module has been alias-resolved
let mod_path_v = path.iter().rev_vec_clone();
if !updated(&mod_path_v) {
@@ -94,20 +104,18 @@ fn collect_aliases_rec(
};
for (&name, target_mod_name) in module.extra.imports_from.iter() {
let target_sym_v = pushed(target_mod_name, name);
assert_visible(&mod_path_v, &target_sym_v, project, i)?;
assert_visible(&mod_path_v, &target_sym_v, project)?;
let sym_path_v = pushed(&mod_path_v, name);
let target_mod = (project.0.walk_ref(target_mod_name, false))
.expect("checked above in assert_visible");
let target_sym = target_mod
.extra
.exports
.get(&name)
let target_sym = (target_mod.extra.exports.get(&name))
.ok_or_else(|| {
let file_len =
target_mod.extra.file.as_ref().unwrap_or(target_mod_name).len();
NotFound {
file: i.extern_all(&target_mod_name[..file_len]),
subpath: i.extern_all(&target_sym_v[file_len..]),
source: Some(mod_path_v.clone()),
file: target_mod_name[..file_len].to_vec(),
subpath: target_sym_v[file_len..].to_vec(),
}
.rc()
})?
@@ -121,7 +129,6 @@ fn collect_aliases_rec(
submodule,
project,
alias_map,
i,
updated,
)?
}
@@ -133,8 +140,7 @@ pub fn collect_aliases(
module: &ProjectModule<VName>,
project: &ProjectTree<VName>,
alias_map: &mut AliasMap,
i: &Interner,
updated: &impl UpdatedFn,
) -> Result<(), Rc<dyn ProjectError>> {
collect_aliases_rec(Substack::Bottom, module, project, alias_map, i, updated)
) -> ProjectResult<()> {
collect_aliases_rec(Substack::Bottom, module, project, alias_map, updated)
}