temp commit

This commit is contained in:
2025-07-12 00:46:10 +02:00
parent 1868f1a506
commit fe89188c4b
60 changed files with 1536 additions and 709 deletions

View File

@@ -14,7 +14,9 @@ pub type Spawner = Rc<dyn Fn(LocalBoxFuture<'static, ()>)>;
///
/// There are no ordering guarantees about these
pub trait ExtPort {
#[must_use]
fn send<'a>(&'a self, msg: &'a [u8]) -> LocalBoxFuture<'a, ()>;
#[must_use]
fn recv(&self) -> LocalBoxFuture<'_, Option<Vec<u8>>>;
}

View File

@@ -39,6 +39,14 @@ impl ErrPos {
impl From<Pos> for ErrPos {
fn from(origin: Pos) -> Self { Self { position: origin, message: None } }
}
impl fmt::Display for ErrPos {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.message {
Some(msg) => write!(f, "{}: {}", self.position, msg),
None => write!(f, "{}", self.position),
}
}
}
#[derive(Clone, Debug)]
pub struct OrcErr {
@@ -71,7 +79,7 @@ impl From<OrcErr> for Vec<OrcErr> {
}
impl fmt::Display for OrcErr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let pstr = self.positions.iter().map(|p| format!("{p:?}")).join("; ");
let pstr = self.positions.iter().map(|p| format!("{p}")).join("; ");
write!(f, "{}: {} @ {}", self.description, self.message, pstr)
}
}
@@ -161,12 +169,12 @@ pub fn mk_err(
}
}
pub fn mk_errv(
pub fn mk_errv<I: Into<ErrPos>>(
description: Tok<String>,
message: impl AsRef<str>,
posv: impl IntoIterator<Item = ErrPos>,
posv: impl IntoIterator<Item = I>,
) -> OrcErrv {
mk_err(description, message, posv).into()
mk_err(description, message, posv.into_iter().map_into()).into()
}
pub struct Reporter {
@@ -177,6 +185,14 @@ impl Reporter {
pub fn report(&self, e: impl Into<OrcErrv>) { self.errors.borrow_mut().extend(e.into()) }
pub fn new() -> Self { Self { errors: RefCell::new(vec![]) } }
pub fn errv(self) -> Option<OrcErrv> { OrcErrv::new(self.errors.into_inner()).ok() }
pub fn merge<T>(self, res: OrcRes<T>) -> OrcRes<T> {
match (res, self.errv()) {
(res, None) => res,
(Ok(_), Some(errv)) => Err(errv),
(Err(e), Some(errv)) => Err(e + errv),
}
}
pub fn is_empty(&self) -> bool { self.errors.borrow().is_empty() }
}
impl Default for Reporter {

View File

@@ -13,6 +13,7 @@ use crate::interner::Interner;
use crate::{api, match_mapping};
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
#[must_use]
pub struct FmtUnit {
pub subs: Vec<FmtUnit>,
pub variants: Rc<Variants>,
@@ -209,6 +210,9 @@ impl From<Rc<String>> for Variants {
impl From<String> for Variants {
fn from(value: String) -> Self { Self::from(Rc::new(value)) }
}
impl From<&str> for Variants {
fn from(value: &str) -> Self { Self::from(value.to_string()) }
}
impl FromStr for Variants {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> { Ok(Self::default().bounded(s)) }
@@ -265,6 +269,7 @@ impl FmtCtx for FmtCtxImpl<'_> {
}
pub trait Format {
#[must_use]
fn print<'a>(&'a self, c: &'a (impl FmtCtx + ?Sized + 'a)) -> impl Future<Output = FmtUnit> + 'a;
}
impl Format for Never {

View File

@@ -6,6 +6,7 @@ use std::ops::Range;
use trait_set::trait_set;
use crate::error::ErrPos;
use crate::interner::{Interner, Tok};
use crate::name::Sym;
use crate::{api, match_mapping, sym};
@@ -51,6 +52,17 @@ impl Pos {
})
}
}
impl fmt::Display for Pos {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Pos::Inherit => f.write_str("Unresolved inherited position"),
Pos::SlotTarget => f.write_str("Unresolved slot target position"),
Pos::None => f.write_str("N/A"),
Pos::Gen(g) => write!(f, "{g}"),
Pos::SrcRange(sr) => write!(f, "{sr}"),
}
}
}
/// Exact source code location. Includes where the code was loaded from, what
/// the original source code was, and a byte range.
@@ -90,13 +102,24 @@ impl SrcRange {
}
}
pub fn zw(path: Sym, pos: u32) -> Self { Self { path, range: pos..pos } }
async fn from_api(api: &api::SourceRange, i: &Interner) -> Self {
pub async fn from_api(api: &api::SourceRange, i: &Interner) -> Self {
Self { path: Sym::from_api(api.path, i).await, range: api.range.clone() }
}
fn to_api(&self) -> api::SourceRange {
pub fn to_api(&self) -> api::SourceRange {
api::SourceRange { path: self.path.to_api(), range: self.range.clone() }
}
}
impl From<SrcRange> for ErrPos {
fn from(val: SrcRange) -> Self { val.pos().into() }
}
impl fmt::Display for SrcRange {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.range.len() {
0 => write!(f, "{}:{}", self.path(), self.range.start),
n => write!(f, "{}:{}+{}", self.path(), self.range.start, n),
}
}
}
/// Information about a code generator attached to the generated code
#[derive(Clone, PartialEq, Eq, Hash)]

View File

@@ -53,12 +53,12 @@ impl VPath {
pub fn into_name(self) -> Result<VName, EmptyNameError> { VName::new(self.0) }
/// Add a token to the path. Since now we know that it can't be empty, turn it
/// into a name.
pub fn name_with_prefix(self, name: Tok<String>) -> VName {
pub fn name_with_suffix(self, name: Tok<String>) -> VName {
VName(self.into_iter().chain([name]).collect())
}
/// Add a token to the beginning of the. Since now we know that it can't be
/// empty, turn it into a name.
pub fn name_with_suffix(self, name: Tok<String>) -> VName {
pub fn name_with_prefix(self, name: Tok<String>) -> VName {
VName([name].into_iter().chain(self).collect())
}
@@ -236,6 +236,9 @@ impl Sym {
Self::from_tok(Tok::from_api(marker, i).await).expect("Empty sequence found for serialized Sym")
}
pub fn to_api(&self) -> api::TStrv { self.tok().to_api() }
pub async fn push(&self, tok: Tok<String>, i: &Interner) -> Sym {
Self::new(self.0.iter().cloned().chain([tok]), i).await.unwrap()
}
}
impl fmt::Debug for Sym {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Sym({self})") }

View File

@@ -15,7 +15,9 @@ use crate::name::{Sym, VName, VPath};
use crate::tree::{ExprRepr, ExtraTok, Paren, TokTree, Token, ttv_range};
pub trait ParseCtx {
#[must_use]
fn i(&self) -> &Interner;
#[must_use]
fn reporter(&self) -> &Reporter;
}
pub struct ParseCtxImpl<'a> {
@@ -171,7 +173,7 @@ pub async fn try_pop_no_fluff<'a, A: ExprRepr, X: ExtraTok>(
None => Err(mk_errv(
ctx.i().i("Unexpected end").await,
"Line ends abruptly; more tokens were expected",
[snip.sr().pos().into()],
[snip.sr()],
)),
}
}
@@ -184,7 +186,7 @@ pub async fn expect_end(
Some(surplus) => Err(mk_errv(
ctx.i().i("Extra code after end of line").await,
"Code found after the end of the line",
[surplus.sr.pos().into()],
[surplus.sr.pos()],
)),
None => Ok(()),
}
@@ -201,7 +203,7 @@ pub async fn expect_tok<'a, A: ExprRepr, X: ExtraTok>(
t => Err(mk_errv(
ctx.i().i("Expected specific keyword").await,
format!("Expected {tok} but found {:?}", fmt(t, ctx.i()).await),
[head.sr.pos().into()],
[head.sr()],
)),
}
}
@@ -221,7 +223,7 @@ pub async fn parse_multiname<'a, A: ExprRepr, X: ExtraTok>(
return Err(mk_errv(
ctx.i().i("Expected token").await,
"Expected a name, a parenthesized list of names, or a globstar.",
[tail.sr().pos().into()],
[tail.sr().pos()],
));
};
let ret = rec(tt, ctx).await;
@@ -264,7 +266,7 @@ pub async fn parse_multiname<'a, A: ExprRepr, X: ExtraTok>(
return Err(mk_errv(
ctx.i().i("Unrecognized name end").await,
format!("Names cannot end with {:?} tokens", fmt(t, ctx.i()).await),
[ttpos.into()],
[ttpos],
));
},
}

View File

@@ -23,12 +23,14 @@ use crate::{api, match_mapping, tl_cache};
pub trait TokenVariant<ApiEquiv: Clone + Debug + Coding>: Format + Clone + fmt::Debug {
type FromApiCtx<'a>;
type ToApiCtx<'a>;
#[must_use]
fn from_api(
api: &ApiEquiv,
ctx: &mut Self::FromApiCtx<'_>,
pos: SrcRange,
i: &Interner,
) -> impl Future<Output = Self>;
#[must_use]
fn into_api(self, ctx: &mut Self::ToApiCtx<'_>) -> impl Future<Output = ApiEquiv>;
}
impl<T: Clone + Debug + Coding> TokenVariant<T> for Never {
@@ -70,7 +72,9 @@ pub fn recur<H: ExprRepr, X: ExtraTok>(
pub trait AtomRepr: Clone + Format {
type Ctx: ?Sized;
#[must_use]
fn from_api(api: &api::Atom, pos: Pos, ctx: &mut Self::Ctx) -> impl Future<Output = Self>;
#[must_use]
fn to_api(&self) -> impl Future<Output = orchid_api::Atom> + '_;
}
impl AtomRepr for Never {
@@ -133,9 +137,9 @@ impl<H: ExprRepr, X: ExtraTok> TokTree<H, X> {
NS(n.to_api(), b => Box::new(b.into_api(hctx, xctx).boxed_local().await)),
Bottom(e.to_api()),
Comment(c.clone()),
LambdaHead(arg => ttv_into_api(arg, hctx, xctx).await),
LambdaHead(arg => ttv_into_api(arg, hctx, xctx).boxed_local().await),
Name(nn.to_api()),
S(p, b => ttv_into_api(b, hctx, xctx).await),
S(p, b => ttv_into_api(b, hctx, xctx).boxed_local().await),
Handle(hand.into_api(hctx).await),
NewExpr(expr.into_api(xctx).await),
});
@@ -163,6 +167,7 @@ impl<H: ExprRepr, X: ExtraTok> TokTree<H, X> {
body.insert(0, Token::LambdaHead(arg).at(arg_range));
Token::S(Paren::Round, body).at(s_range)
}
pub fn sr(&self) -> SrcRange { self.sr.clone() }
}
impl<H: ExprRepr, X: ExtraTok> Format for TokTree<H, X> {
async fn print<'a>(&'a self, c: &'a (impl FmtCtx + ?Sized + 'a)) -> FmtUnit {