transfer commit

This commit is contained in:
2023-02-03 14:40:34 +00:00
parent a500f8b87a
commit 3c63cae242
63 changed files with 3227 additions and 2850 deletions

View File

@@ -4,7 +4,7 @@ use ordered_float::NotNan;
use std::{hash::Hash, intrinsics::likely};
use std::fmt::Debug;
use crate::utils::mrc_empty_slice;
use crate::{executor::{ExternFn, Atom}, utils::one_mrc_slice};
use crate::{foreign::{ExternFn, Atom}, utils::one_mrc_slice};
use super::Literal;
@@ -12,167 +12,167 @@ use super::Literal;
#[derive(PartialEq, Eq, Hash)]
pub struct Expr(pub Clause, pub Mrc<[Clause]>);
impl Expr {
pub fn into_clause(self) -> Clause {
if likely(self.1.len() == 0) { self.0 }
else { Clause::S('(', one_mrc_slice(self)) }
}
pub fn into_clause(self) -> Clause {
if likely(self.1.len() == 0) { self.0 }
else { Clause::S('(', one_mrc_slice(self)) }
}
}
impl Clone for Expr {
fn clone(&self) -> Self {
Self(self.0.clone(), Mrc::clone(&self.1))
}
fn clone(&self) -> Self {
Self(self.0.clone(), Mrc::clone(&self.1))
}
}
impl Debug for Expr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Expr(val, typ) = self;
write!(f, "{:?}", val)?;
for typ in typ.as_ref() {
write!(f, ":{:?}", typ)?
}
Ok(())
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Expr(val, typ) = self;
write!(f, "{:?}", val)?;
for typ in typ.as_ref() {
write!(f, ":{:?}", typ)?
}
Ok(())
}
}
/// An S-expression as read from a source file
#[derive(PartialEq, Eq, Hash)]
pub enum Clause {
Literal(Literal),
Name{
local: Option<String>,
qualified: Mrc<[String]>
},
S(char, Mrc<[Expr]>),
Explicit(Mrc<Expr>),
Lambda(String, Mrc<[Expr]>, Mrc<[Expr]>),
Auto(Option<String>, Mrc<[Expr]>, Mrc<[Expr]>),
ExternFn(ExternFn),
Atom(Atom),
Placeh{
key: String,
/// None => matches one token
/// Some((prio, nonzero)) =>
/// 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)>
},
Literal(Literal),
Name{
local: Option<String>,
qualified: Mrc<[String]>
},
S(char, Mrc<[Expr]>),
Explicit(Mrc<Expr>),
Lambda(String, Mrc<[Expr]>, Mrc<[Expr]>),
Auto(Option<String>, Mrc<[Expr]>, Mrc<[Expr]>),
ExternFn(ExternFn),
Atom(Atom),
Placeh{
key: String,
/// None => matches one token
/// Some((prio, nonzero)) =>
/// 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]>> {
match self {
Self::Auto(_, _, body) |
Self::Lambda(_, _, body) |
Self::S(_, body) => Some(Mrc::clone(body)),
_ => None
}
pub fn body(&self) -> Option<Mrc<[Expr]>> {
match self {
Self::Auto(_, _, body) |
Self::Lambda(_, _, body) |
Self::S(_, body) => Some(Mrc::clone(body)),
_ => None
}
pub fn typ(&self) -> Option<Mrc<[Expr]>> {
match self {
Self::Auto(_, typ, _) | Self::Lambda(_, typ, _) => Some(Mrc::clone(typ)),
_ => 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()) }
}
pub fn from_exprv(exprv: Mrc<[Expr]>) -> Option<Clause> {
if exprv.len() == 0 { None }
else if exprv.len() == 1 { Some(exprv[0].clone().into_clause()) }
else { Some(Self::S('(', exprv)) }
}
pub fn typ(&self) -> Option<Mrc<[Expr]>> {
match self {
Self::Auto(_, typ, _) | Self::Lambda(_, typ, _) => Some(Mrc::clone(typ)),
_ => 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()) }
}
pub fn from_exprv(exprv: Mrc<[Expr]>) -> Option<Clause> {
if exprv.len() == 0 { None }
else if exprv.len() == 1 { Some(exprv[0].clone().into_clause()) }
else { Some(Self::S('(', exprv)) }
}
}
impl Clone for Clause {
fn clone(&self) -> Self {
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)
},
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::Literal(l) => Self::Literal(l.clone()),
Self::ExternFn(nc) => Self::ExternFn(nc.clone()),
Self::Atom(a) => Self::Atom(a.clone()),
Self::Explicit(expr) => Self::Explicit(Mrc::clone(expr))
}
fn clone(&self) -> Self {
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)
},
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::Literal(l) => Self::Literal(l.clone()),
Self::ExternFn(nc) => Self::ExternFn(nc.clone()),
Self::Atom(a) => Self::Atom(a.clone()),
Self::Explicit(expr) => Self::Explicit(Mrc::clone(expr))
}
}
}
fn fmt_expr_seq(it: &mut dyn Iterator<Item = &Expr>, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for item in Itertools::intersperse(it.map(Some), None) { match item {
Some(expr) => write!(f, "{:?}", expr),
None => f.write_str(" "),
}? }
Ok(())
for item in Itertools::intersperse(it.map(Some), None) { match item {
Some(expr) => write!(f, "{:?}", expr),
None => f.write_str(" "),
}? }
Ok(())
}
impl Debug for Clause {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Literal(arg0) => write!(f, "{:?}", arg0),
Self::Name{local, qualified} =>
if let Some(local) = local {write!(f, "{}`{}`", qualified.join("::"), local)}
else {write!(f, "{}", qualified.join("::"))},
Self::S(del, items) => {
f.write_str(&del.to_string())?;
fmt_expr_seq(&mut items.iter(), f)?;
f.write_str(match del {
'(' => ")", '[' => "]", '{' => "}",
_ => "CLOSING_DELIM"
})
},
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)
},
Self::Auto(name, 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)
},
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::ExternFn(nc) => write!(f, "{nc:?}"),
Self::Atom(a) => write!(f, "{a:?}"),
Self::Explicit(expr) => write!(f, "@{:?}", expr.as_ref())
}
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Literal(arg0) => write!(f, "{:?}", arg0),
Self::Name{local, qualified} =>
if let Some(local) = local {write!(f, "{}`{}`", qualified.join("::"), local)}
else {write!(f, "{}", qualified.join("::"))},
Self::S(del, items) => {
f.write_str(&del.to_string())?;
fmt_expr_seq(&mut items.iter(), f)?;
f.write_str(match del {
'(' => ")", '[' => "]", '{' => "}",
_ => "CLOSING_DELIM"
})
},
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)
},
Self::Auto(name, 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)
},
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::ExternFn(nc) => write!(f, "{nc:?}"),
Self::Atom(a) => write!(f, "{a:?}"),
Self::Explicit(expr) => write!(f, "@{:?}", expr.as_ref())
}
}
}
/// A substitution rule as read from the source
#[derive(PartialEq, Eq, Hash)]
pub struct Rule {
pub source: Mrc<[Expr]>,
pub prio: NotNan<f64>,
pub target: Mrc<[Expr]>
pub source: Mrc<[Expr]>,
pub prio: NotNan<f64>,
pub target: Mrc<[Expr]>
}
impl Clone for Rule {
fn clone(&self) -> Self {
Self {
source: Mrc::clone(&self.source),
prio: self.prio,
target: Mrc::clone(&self.target)
}
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)
}
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?} ={}=> {:?}", self.source, self.prio, self.target)
}
}