Public API and docs

This commit is contained in:
2023-05-26 15:23:15 +01:00
parent 3c1a6e2be2
commit fdf18e6ff8
99 changed files with 503 additions and 406 deletions

View File

@@ -1,6 +1,7 @@
use std::rc::Rc;
use hashbrown::HashMap;
use itertools::Itertools;
use super::collect_ops::InjectedOperatorsFn;
use super::parse_file::parse_file;
@@ -87,7 +88,7 @@ fn source_to_module(
Member::Namespace(ns) => box_once(mk_ent(ns.name)),
Member::Rule(rule) => {
let mut names = Vec::new();
for e in rule.source.iter() {
for e in rule.pattern.iter() {
e.visit_names(Substack::Bottom, &mut |n| {
if let Some([name]) = i.r(n).strip_prefix(&path_v[..]) {
names.push((*name, n))
@@ -177,7 +178,7 @@ fn source_to_module(
fn files_to_module(
path: Substack<Tok<String>>,
files: &[ParsedSource],
files: Vec<ParsedSource>,
i: &Interner,
) -> Rc<Module<Expr, ProjectExt>> {
let lvl = path.len();
@@ -192,11 +193,13 @@ fn files_to_module(
);
}
let items = files
.group_by(|a, b| a.path[lvl] == b.path[lvl])
.map(|files| {
let namespace = files[0].path[lvl];
.into_iter()
.group_by(|f| f.path[lvl])
.into_iter()
.map(|(namespace, files)| {
let subpath = path.push(namespace);
let module = files_to_module(subpath, files, i);
let files_v = files.collect::<Vec<_>>();
let module = files_to_module(subpath, files_v, i);
let member = ModMember::Sub(module);
(namespace, ModEntry { exported: true, member })
})
@@ -206,11 +209,6 @@ fn files_to_module(
.copied()
.map(|name| (name, i.i(&pushed(&path_v, name))))
.collect();
// println!(
// "Constructing module {} with items ({})",
// i.extern_all(&path_v[..]).join("::"),
// exports.keys().map(|t| i.r(*t)).join(", ")
// );
Rc::new(Module {
items,
imports: vec![],
@@ -250,5 +248,5 @@ pub fn build_tree(
path: path.clone(),
})
.collect::<Vec<_>>();
Ok(ProjectTree(files_to_module(Substack::Bottom, &files, i)))
Ok(ProjectTree(files_to_module(Substack::Bottom, files, i)))
}

View File

@@ -3,6 +3,7 @@ use std::rc::Rc;
use hashbrown::HashSet;
use itertools::Itertools;
use trait_set::trait_set;
use crate::interner::{Interner, Sym, Tok};
use crate::pipeline::error::{ModuleNotFound, ProjectError};
@@ -14,7 +15,9 @@ use crate::utils::Cache;
pub type OpsResult = Result<Rc<HashSet<Tok<String>>>, Rc<dyn ProjectError>>;
pub type ExportedOpsCache<'a> = Cache<'a, Sym, OpsResult>;
pub trait InjectedOperatorsFn = Fn(Sym) -> Option<Rc<HashSet<Tok<String>>>>;
trait_set! {
pub trait InjectedOperatorsFn = Fn(Sym) -> Option<Rc<HashSet<Tok<String>>>>;
}
fn coprefix<T: Eq>(
l: impl Iterator<Item = T>,

View File

@@ -12,23 +12,30 @@ use crate::representations::tree::{ModEntry, ModMember, Module};
use crate::representations::Primitive;
use crate::utils::{pushed, Substack};
/// A lightweight module tree that can be built declaratively by hand to
/// describe libraries of external functions in Rust. It implements [Add] for
/// added convenience
pub enum ConstTree {
Const(Expr),
Tree(HashMap<Tok<String>, ConstTree>),
}
impl ConstTree {
/// Describe a [Primitive]
pub fn primitive(primitive: Primitive) -> Self {
Self::Const(Expr {
location: Location::Unknown,
value: Clause::P(primitive),
})
}
/// Describe an [ExternFn]
pub fn xfn(xfn: impl ExternFn + 'static) -> Self {
Self::primitive(Primitive::ExternFn(Box::new(xfn)))
}
/// Describe an [Atomic]
pub fn atom(atom: impl Atomic + 'static) -> Self {
Self::primitive(Primitive::Atom(Atom(Box::new(atom))))
}
/// Describe a module
pub fn tree(arr: impl IntoIterator<Item = (Tok<String>, Self)>) -> Self {
Self::Tree(arr.into_iter().collect())
}
@@ -89,6 +96,8 @@ fn from_const_tree_rec(
}
}
/// Convert a map of [ConstTree] into a [ProjectTree] that can be used with the
/// layered parsing system
pub fn from_const_tree(
consts: HashMap<Tok<String>, ConstTree>,
file: &[Tok<String>],

View File

@@ -35,11 +35,11 @@ fn member_rec(
}),
Member::Rule(rule) => Member::Rule(Rule {
prio: rule.prio,
source: Rc::new(
rule.source.iter().map(|e| e.prefix(prefix, i, &except)).collect(),
pattern: Rc::new(
rule.pattern.iter().map(|e| e.prefix(prefix, i, &except)).collect(),
),
target: Rc::new(
rule.target.iter().map(|e| e.prefix(prefix, i, &except)).collect(),
template: Rc::new(
rule.template.iter().map(|e| e.prefix(prefix, i, &except)).collect(),
),
}),
}

View File

@@ -8,11 +8,13 @@ use crate::interner::{Interner, Sym, Tok};
use crate::representations::tree::{ModMember, Module};
use crate::utils::Substack;
/// Additional data about a loaded module beyond the list of constants and
/// submodules
#[derive(Clone, Debug, Default)]
pub struct ProjectExt {
/// Pairs each foreign token to the module it was imported from
pub imports_from: HashMap<Tok<String>, Sym>,
/// Pairs each exported token to its original full name.
/// Pairs each exported token to its original full name
pub exports: HashMap<Tok<String>, Sym>,
/// All rules defined in this module, exported or not
pub rules: Vec<Rule>,
@@ -35,7 +37,10 @@ impl Add for ProjectExt {
}
}
/// A node in the tree describing the project
pub type ProjectModule = Module<Expr, ProjectExt>;
/// Module corresponding to the root of a project
pub struct ProjectTree(pub Rc<ProjectModule>);
fn collect_rules_rec(bag: &mut Vec<Rule>, module: &ProjectModule) {
@@ -47,6 +52,8 @@ fn collect_rules_rec(bag: &mut Vec<Rule>, module: &ProjectModule) {
}
}
/// Collect the complete list of rules to be used by the rule repository from
/// the [ProjectTree]
pub fn collect_rules(project: &ProjectTree) -> Vec<Rule> {
let mut rules = Vec::new();
collect_rules_rec(&mut rules, project.0.as_ref());
@@ -72,6 +79,7 @@ fn collect_consts_rec(
}
}
/// Extract the symbol table from a [ProjectTree]
pub fn collect_consts(
project: &ProjectTree,
i: &Interner,