Transfer commit

This commit is contained in:
2023-03-21 19:36:40 +00:00
parent 180ebb56fa
commit f3ce910f66
63 changed files with 1410 additions and 1023 deletions

View File

@@ -1,133 +1,193 @@
use mappable_rc::Mrc;
use lasso::RodeoResolver;
use lasso::Spur;
use itertools::Itertools;
use ordered_float::NotNan;
use std::{hash::Hash, intrinsics::likely};
use std::fmt::Debug;
use crate::utils::mrc_empty_slice;
use crate::utils::one_mrc_slice;
use std::hash::Hash;
use std::rc::Rc;
use crate::utils::InternedDisplay;
use crate::utils::Stackframe;
use super::primitive::Primitive;
/// An S-expression with a type
#[derive(PartialEq, Eq, Hash)]
pub struct Expr(pub Clause, pub Mrc<[Clause]>);
pub struct Expr(pub Clause, pub Rc<Vec<Clause>>);
impl Expr {
pub fn into_clause(self) -> Clause {
if likely(self.1.len() == 0) { self.0 }
else { Clause::S('(', one_mrc_slice(self)) }
if self.1.len() == 0 { self.0 }
else { Clause::S('(', Rc::new(vec![self])) }
}
pub fn visit_names<F>(&self,
binds: Stackframe<Rc<Vec<Spur>>>,
cb: &mut F
) where F: FnMut(Rc<Vec<Spur>>) {
let Expr(val, typ) = self;
val.visit_names(binds.clone(), cb);
for typ in typ.as_ref() {
typ.visit_names(binds.clone(), cb);
}
}
}
impl Clone for Expr {
fn clone(&self) -> Self {
Self(self.0.clone(), Mrc::clone(&self.1))
Self(self.0.clone(), self.1.clone())
}
}
impl Debug for Expr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
impl InternedDisplay for Expr {
fn fmt(&self,
f: &mut std::fmt::Formatter<'_>,
rr: RodeoResolver
) -> std::fmt::Result {
let Expr(val, typ) = self;
write!(f, "{:?}", val)?;
val.fmt(f, rr)?;
for typ in typ.as_ref() {
write!(f, ":{:?}", typ)?
write!(f, ":")?;
typ.fmt(f, rr)?;
}
Ok(())
}
}
/// An S-expression as read from a source file
#[derive(PartialEq, Eq, Hash)]
#[derive(PartialEq, Eq, Hash, Clone)]
pub enum Clause {
P(Primitive),
/// A c-style name or an operator, eg. `+`, `i`, `foo::bar`
Name{
local: Option<String>,
qualified: Mrc<[String]>
},
/// A parenthesized expression, eg. `(print out "hello")`, `[1, 2, 3]`, `{Some(t) => t}`
S(char, Mrc<[Expr]>),
/// An explicit expression associated with the leftmost, outermost [Clause::Auto], eg. `read @Uint`
Explicit(Mrc<Expr>),
Name(Rc<Vec<Spur>>),
/// A parenthesized exmrc_empty_slice()pression
/// eg. `(print out "hello")`, `[1, 2, 3]`, `{Some(t) => t}`
S(char, Rc<Vec<Expr>>),
/// An explicit expression associated with the leftmost, outermost
/// [Clause::Auto], eg. `read @Uint`
Explicit(Rc<Expr>),
/// A function expression, eg. `\x. x + 1`
Lambda(String, Mrc<[Expr]>, Mrc<[Expr]>),
Lambda(Rc<Clause>, Rc<Vec<Expr>>, Rc<Vec<Expr>>),
/// A parameterized expression with type inference, eg. `@T. T -> T`
Auto(Option<String>, Mrc<[Expr]>, Mrc<[Expr]>),
Auto(Option<Rc<Clause>>, Rc<Vec<Expr>>, Rc<Vec<Expr>>),
/// A placeholder for macros, eg. `$name`, `...$body`, `...$lhs:1`
Placeh{
key: String,
/// None => matches one token
/// Some((prio, nonzero)) =>
/// prio is the sizing priority for the vectorial (higher prio grows first)
/// prio is the sizing priority for the vectorial
/// (higher prio grows first)
/// nonzero is whether the vectorial matches 1..n or 0..n tokens
vec: Option<(usize, bool)>
},
}
impl Clause {
pub fn body(&self) -> Option<Mrc<[Expr]>> {
pub fn body(&self) -> Option<Rc<Vec<Expr>>> {
match self {
Self::Auto(_, _, body) |
Self::Lambda(_, _, body) |
Self::S(_, body) => Some(Mrc::clone(body)),
Self::S(_, body) => Some(body.clone()),
_ => None
}
}
pub fn typ(&self) -> Option<Mrc<[Expr]>> {
pub fn typ(&self) -> Option<Rc<Vec<Expr>>> {
match self {
Self::Auto(_, typ, _) | Self::Lambda(_, typ, _) => Some(Mrc::clone(typ)),
Self::Auto(_, typ, _) | Self::Lambda(_, typ, _) => Some(typ.clone()),
_ => None
}
}
pub fn into_expr(self) -> Expr {
if let Self::S('(', body) = &self {
if body.len() == 1 { body[0].clone() }
else { Expr(self, mrc_empty_slice()) }
} else { Expr(self, mrc_empty_slice()) }
else { Expr(self, Rc::default()) }
} else { Expr(self, Rc::default()) }
}
pub fn from_exprv(exprv: Mrc<[Expr]>) -> Option<Clause> {
pub fn from_exprv(exprv: &[Expr]) -> Option<Clause> {
if exprv.len() == 0 { None }
else if exprv.len() == 1 { Some(exprv[0].clone().into_clause()) }
else { Some(Self::S('(', exprv)) }
else { Some(Self::S('(', Rc::new(exprv.to_vec()))) }
}
}
impl Clone for Clause {
fn clone(&self) -> Self {
/// Recursively iterate through all "names" in an expression.
/// It also finds a lot of things that aren't names, such as all
/// bound parameters. Generally speaking, this is not a very
/// sophisticated search.
pub fn visit_names<F>(&self,
binds: Stackframe<Rc<Vec<Spur>>>,
cb: &mut F
) where F: FnMut(Rc<Vec<Spur>>) {
match self {
Self::S(c, b) => Self::S(*c, Mrc::clone(b)),
Self::Auto(n, t, b) => Self::Auto(
n.clone(), Mrc::clone(t), Mrc::clone(b)
),
Self::Name { local: l, qualified: q } => Self::Name {
local: l.clone(), qualified: Mrc::clone(q)
Clause::Auto(name, typ, body) => {
for x in typ.iter() {
x.visit_names(binds.clone(), cb)
}
let binds_dup = binds.clone();
let new_binds = if let Some(rc) = name {
if let Clause::Name(name) = rc.as_ref() {
binds_dup.push(name.clone())
} else { binds }
} else { binds };
for x in body.iter() {
x.visit_names(new_binds.clone(), cb)
}
},
Self::Lambda(n, t, b) => Self::Lambda(
n.clone(), Mrc::clone(t), Mrc::clone(b)
),
Self::Placeh{key, vec} => Self::Placeh{key: key.clone(), vec: *vec},
Self::P(p) => Self::P(p.clone()),
Self::Explicit(expr) => Self::Explicit(Mrc::clone(expr))
Clause::Lambda(name, typ, body) => {
for x in typ.iter() {
x.visit_names(binds.clone(), cb)
}
for x in body.iter() {
let new_binds = if let Clause::Name(name) = name.as_ref() {
binds.push(name.clone())
} else { binds };
x.visit_names(new_binds, cb)
}
},
Clause::S(_, body) => for x in body.iter() {
x.visit_names(binds.clone(), cb)
},
Clause::Name(name) => {
if binds.iter().all(|x| x != name) {
cb(name.clone())
}
}
_ => (),
}
}
}
fn fmt_expr_seq(it: &mut dyn Iterator<Item = &Expr>, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fn fmt_expr_seq(
it: &mut dyn Iterator<Item = &Expr>,
f: &mut std::fmt::Formatter<'_>,
rr: RodeoResolver
) -> std::fmt::Result {
for item in Itertools::intersperse(it.map(Some), None) { match item {
Some(expr) => write!(f, "{:?}", expr),
Some(expr) => expr.fmt(f, rr),
None => f.write_str(" "),
}? }
Ok(())
}
impl Debug for Clause {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
pub fn fmt_name(
name: &Rc<Vec<Spur>>, f: &mut std::fmt::Formatter, rr: RodeoResolver
) -> std::fmt::Result {
for el in itertools::intersperse(
name.iter().map(|s| rr.resolve(s)),
"::"
) {
write!(f, "{}", el)?
}
Ok(())
}
impl InternedDisplay for Clause {
fn fmt(&self,
f: &mut std::fmt::Formatter<'_>,
rr: RodeoResolver
) -> std::fmt::Result {
match self {
Self::P(p) => write!(f, "{:?}", p),
Self::Name{local, qualified} =>
if let Some(local) = local {write!(f, "{}`{}`", qualified.join("::"), local)}
else {write!(f, "{}", qualified.join("::"))},
Self::Name(name) => fmt_name(name, f, rr),
Self::S(del, items) => {
f.write_str(&del.to_string())?;
fmt_expr_seq(&mut items.iter(), f)?;
fmt_expr_seq(&mut items.iter(), f, rr)?;
f.write_str(match del {
'(' => ")", '[' => "]", '{' => "}",
_ => "CLOSING_DELIM"
@@ -135,44 +195,49 @@ impl Debug for Clause {
},
Self::Lambda(name, argtyp, body) => {
f.write_str("\\")?;
f.write_str(name)?;
f.write_str(":")?; fmt_expr_seq(&mut argtyp.iter(), f)?; f.write_str(".")?;
fmt_expr_seq(&mut body.iter(), f)
name.fmt(f, rr)?;
f.write_str(":")?;
fmt_expr_seq(&mut argtyp.iter(), f, rr)?;
f.write_str(".")?;
fmt_expr_seq(&mut body.iter(), f, rr)
},
Self::Auto(name, argtyp, body) => {
Self::Auto(name_opt, argtyp, body) => {
f.write_str("@")?;
f.write_str(&name.clone().unwrap_or_default())?;
f.write_str(":")?; fmt_expr_seq(&mut argtyp.iter(), f)?; f.write_str(".")?;
fmt_expr_seq(&mut body.iter(), f)
if let Some(name) = name_opt { name.fmt(f, rr)? }
f.write_str(":")?;
fmt_expr_seq(&mut argtyp.iter(), f, rr)?;
f.write_str(".")?;
fmt_expr_seq(&mut body.iter(), f, rr)
},
Self::Placeh{key, vec: None} => write!(f, "${key}"),
Self::Placeh{key, vec: Some((prio, true))} => write!(f, "...${key}:{prio}"),
Self::Placeh{key, vec: Some((prio, false))} => write!(f, "..${key}:{prio}"),
Self::Explicit(expr) => write!(f, "@{:?}", expr.as_ref())
Self::Placeh{key, vec: Some((prio, true))} =>
write!(f, "...${key}:{prio}"),
Self::Placeh{key, vec: Some((prio, false))} =>
write!(f, "..${key}:{prio}"),
Self::Explicit(expr) => {
write!(f, "@")?;
expr.fmt(f, rr)
}
}
}
}
/// A substitution rule as read from the source
#[derive(PartialEq, Eq, Hash)]
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Rule {
pub source: Mrc<[Expr]>,
pub source: Rc<Vec<Expr>>,
pub prio: NotNan<f64>,
pub target: Mrc<[Expr]>
pub target: Rc<Vec<Expr>>
}
impl Clone for Rule {
fn clone(&self) -> Self {
Self {
source: Mrc::clone(&self.source),
prio: self.prio,
target: Mrc::clone(&self.target)
}
}
}
impl Debug for Rule {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?} ={}=> {:?}", self.source, self.prio, self.target)
impl InternedDisplay for Rule {
fn fmt(&self,
f: &mut std::fmt::Formatter<'_>,
rr: RodeoResolver
) -> std::fmt::Result {
for e in self.source.iter() { e.fmt(f, rr)?; write!(f, " ")?; }
write!(f, "={}=>", self.prio)?;
for e in self.target.iter() { write!(f, " ")?; e.fmt(f, rr)?; }
Ok(())
}
}