Various progress, doesnt compile
Added prelude, made lambdas a single-token prefix like NS, made progress on implementations, removed const line type
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
#[macro_export]
|
||||
macro_rules! clone {
|
||||
($($n:ident),+; $body:expr) => (
|
||||
($($n:ident $($mut:ident)?),+; $body:expr) => (
|
||||
{
|
||||
$( let $n = $n.clone(); )+
|
||||
$( let $($mut)? $n = $n.clone(); )+
|
||||
$body
|
||||
}
|
||||
);
|
||||
|
||||
@@ -15,7 +15,7 @@ trait_set! {
|
||||
pub trait GetSrc = FnMut(&Sym) -> Tok<String>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Pos {
|
||||
None,
|
||||
SlotTarget,
|
||||
|
||||
@@ -272,34 +272,34 @@ pub trait NameLike:
|
||||
/// Convert into held slice
|
||||
fn as_slice(&self) -> &[Tok<String>] { Borrow::<[Tok<String>]>::borrow(self) }
|
||||
/// Get iterator over tokens
|
||||
fn iter(&self) -> impl NameIter + '_ { self.as_slice().iter().cloned() }
|
||||
fn segs(&self) -> impl NameIter + '_ { self.as_slice().iter().cloned() }
|
||||
/// Get iterator over string segments
|
||||
fn str_iter(&self) -> impl Iterator<Item = &'_ str> + '_ {
|
||||
self.as_slice().iter().map(|t| t.as_str())
|
||||
}
|
||||
/// Fully resolve the name for printing
|
||||
#[must_use]
|
||||
fn to_strv(&self) -> Vec<String> { self.iter().map(|s| s.to_string()).collect() }
|
||||
fn to_strv(&self) -> Vec<String> { self.segs().map(|s| s.to_string()).collect() }
|
||||
/// Format the name as an approximate filename
|
||||
fn as_src_path(&self) -> String { format!("{}.orc", self.iter().join("/")) }
|
||||
fn as_src_path(&self) -> String { format!("{}.orc", self.segs().join("/")) }
|
||||
/// Return the number of segments in the name
|
||||
fn len(&self) -> NonZeroUsize {
|
||||
NonZeroUsize::try_from(self.iter().count()).expect("NameLike never empty")
|
||||
fn len_nz(&self) -> NonZeroUsize {
|
||||
NonZeroUsize::try_from(self.segs().count()).expect("NameLike never empty")
|
||||
}
|
||||
/// Like slice's `split_first` except we know that it always returns Some
|
||||
fn split_first(&self) -> (Tok<String>, &[Tok<String>]) {
|
||||
fn split_first_seg(&self) -> (Tok<String>, &[Tok<String>]) {
|
||||
let (foot, torso) = self.as_slice().split_last().expect("NameLike never empty");
|
||||
(foot.clone(), torso)
|
||||
}
|
||||
/// Like slice's `split_last` except we know that it always returns Some
|
||||
fn split_last(&self) -> (Tok<String>, &[Tok<String>]) {
|
||||
fn split_last_seg(&self) -> (Tok<String>, &[Tok<String>]) {
|
||||
let (foot, torso) = self.as_slice().split_last().expect("NameLike never empty");
|
||||
(foot.clone(), torso)
|
||||
}
|
||||
/// Get the first element
|
||||
fn first(&self) -> Tok<String> { self.split_first().0 }
|
||||
fn first_seg(&self) -> Tok<String> { self.split_first_seg().0 }
|
||||
/// Get the last element
|
||||
fn last(&self) -> Tok<String> { self.split_last().0 }
|
||||
fn last_seg(&self) -> Tok<String> { self.split_last_seg().0 }
|
||||
}
|
||||
|
||||
impl NameLike for Sym {}
|
||||
|
||||
@@ -7,12 +7,12 @@ use futures::future::join_all;
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::api;
|
||||
use crate::error::{OrcRes, Reporter, mk_err, mk_errv};
|
||||
use crate::format::fmt;
|
||||
use crate::error::{OrcErrv, OrcRes, Reporter, mk_err, mk_errv};
|
||||
use crate::format::{FmtCtx, FmtUnit, Format, fmt};
|
||||
use crate::interner::{Interner, Tok};
|
||||
use crate::location::SrcRange;
|
||||
use crate::name::{Sym, VName, VPath};
|
||||
use crate::tree::{ExprRepr, ExtraTok, Paren, TokTree, Token, ttv_range};
|
||||
use crate::tree::{ExprRepr, ExtraTok, Paren, TokTree, Token, ttv_fmt, ttv_range};
|
||||
|
||||
pub trait ParseCtx {
|
||||
#[must_use]
|
||||
@@ -95,18 +95,10 @@ impl<A: ExprRepr, X: ExtraTok> Deref for Snippet<'_, A, X> {
|
||||
type Target = [TokTree<A, X>];
|
||||
fn deref(&self) -> &Self::Target { self.cur }
|
||||
}
|
||||
|
||||
/// Remove tokens that aren't meaningful in expression context, such as comments
|
||||
/// or line breaks
|
||||
pub fn strip_fluff<A: ExprRepr, X: ExtraTok>(tt: &TokTree<A, X>) -> Option<TokTree<A, X>> {
|
||||
let tok = match &tt.tok {
|
||||
Token::BR => return None,
|
||||
Token::Comment(_) => return None,
|
||||
Token::LambdaHead(arg) => Token::LambdaHead(arg.iter().filter_map(strip_fluff).collect()),
|
||||
Token::S(p, b) => Token::S(*p, b.iter().filter_map(strip_fluff).collect()),
|
||||
t => t.clone(),
|
||||
};
|
||||
Some(TokTree { tok, sr: tt.sr.clone() })
|
||||
impl<A: ExprRepr, X: ExtraTok> Format for Snippet<'_, A, X> {
|
||||
async fn print<'a>(&'a self, c: &'a (impl FmtCtx + ?Sized + 'a)) -> FmtUnit {
|
||||
ttv_fmt(&**self, c).await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -208,6 +200,15 @@ pub async fn expect_tok<'a, A: ExprRepr, X: ExtraTok>(
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn token_errv<A: ExprRepr, X: ExtraTok>(
|
||||
ctx: &impl ParseCtx,
|
||||
tok: &TokTree<A, X>,
|
||||
description: &'static str,
|
||||
message: impl FnOnce(&str) -> String,
|
||||
) -> OrcErrv {
|
||||
mk_errv(ctx.i().i(description).await, message(&fmt(tok, ctx.i()).await), [tok.sr.pos()])
|
||||
}
|
||||
|
||||
pub struct Parsed<'a, T, H: ExprRepr, X: ExtraTok> {
|
||||
pub output: T,
|
||||
pub tail: Snippet<'a, H, X>,
|
||||
|
||||
@@ -62,8 +62,7 @@ pub fn recur<H: ExprRepr, X: ExtraTok>(
|
||||
tok @ (Token::BR | Token::Bottom(_) | Token::Comment(_) | Token::Name(_)) => tok,
|
||||
tok @ (Token::Handle(_) | Token::NewExpr(_)) => tok,
|
||||
Token::NS(n, b) => Token::NS(n, Box::new(recur(*b, f))),
|
||||
Token::LambdaHead(arg) =>
|
||||
Token::LambdaHead(arg.into_iter().map(|tt| recur(tt, f)).collect_vec()),
|
||||
Token::LambdaHead(arg) => Token::LambdaHead(Box::new(recur(*arg, f))),
|
||||
Token::S(p, b) => Token::S(p, b.into_iter().map(|tt| recur(tt, f)).collect_vec()),
|
||||
};
|
||||
TokTree { sr: range, tok }
|
||||
@@ -117,7 +116,7 @@ impl<H: ExprRepr, X: ExtraTok> TokTree<H, X> {
|
||||
NS(n => Tok::from_api(*n, i).await,
|
||||
b => Box::new(Self::from_api(b, hctx, xctx, src, i).boxed_local().await)),
|
||||
Bottom(e => OrcErrv::from_api(e, i).await),
|
||||
LambdaHead(arg => ttv_from_api(arg, hctx, xctx, src, i).await),
|
||||
LambdaHead(arg => Box::new(Self::from_api(arg, hctx, xctx, src, i).boxed_local().await)),
|
||||
Name(n => Tok::from_api(*n, i).await),
|
||||
S(*par, b => ttv_from_api(b, hctx, xctx, src, i).await),
|
||||
Comment(c.clone()),
|
||||
@@ -137,7 +136,7 @@ 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).boxed_local().await),
|
||||
LambdaHead(arg => Box::new(arg.into_api(hctx, xctx).boxed_local().await)),
|
||||
Name(nn.to_api()),
|
||||
S(p, b => ttv_into_api(b, hctx, xctx).boxed_local().await),
|
||||
Handle(hand.into_api(hctx).await),
|
||||
@@ -153,18 +152,18 @@ impl<H: ExprRepr, X: ExtraTok> TokTree<H, X> {
|
||||
pub fn as_s(&self, par: Paren) -> Option<Snippet<'_, H, X>> {
|
||||
self.tok.as_s(par).map(|slc| Snippet::new(self, slc))
|
||||
}
|
||||
pub fn as_lambda(&self) -> Option<Snippet<'_, H, X>> {
|
||||
pub fn as_lambda(&self) -> Option<&Self> {
|
||||
match &self.tok {
|
||||
Token::LambdaHead(arg) => Some(Snippet::new(self, arg)),
|
||||
Token::LambdaHead(arg) => Some(&**arg),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
pub fn is_fluff(&self) -> bool { matches!(self.tok, Token::Comment(_) | Token::BR) }
|
||||
pub fn lambda(arg: Vec<Self>, mut body: Vec<Self>) -> Self {
|
||||
let arg_range = ttv_range(&arg).expect("Lambda with empty arg!");
|
||||
pub fn lambda(arg: Self, mut body: Vec<Self>) -> Self {
|
||||
let arg_range = arg.sr();
|
||||
let mut s_range = arg_range.clone();
|
||||
s_range.range.end = body.last().expect("Lambda with empty body!").sr.range.end;
|
||||
body.insert(0, Token::LambdaHead(arg).at(arg_range));
|
||||
body.insert(0, Token::LambdaHead(Box::new(arg)).at(arg_range));
|
||||
Token::S(Paren::Round, body).at(s_range)
|
||||
}
|
||||
pub fn sr(&self) -> SrcRange { self.sr.clone() }
|
||||
@@ -230,7 +229,7 @@ pub enum Token<H: ExprRepr, X: ExtraTok> {
|
||||
Comment(Rc<String>),
|
||||
/// The part of a lambda between `\` and `.` enclosing the argument. The body
|
||||
/// stretches to the end of the enclosing parens or the end of the const line
|
||||
LambdaHead(Vec<TokTree<H, X>>),
|
||||
LambdaHead(Box<TokTree<H, X>>),
|
||||
/// A binding, operator, or a segment of a namespaced::name
|
||||
Name(Tok<String>),
|
||||
/// A namespace prefix, like `my_ns::` followed by a token
|
||||
@@ -267,7 +266,7 @@ impl<H: ExprRepr, X: ExtraTok> Format for Token<H, X> {
|
||||
Self::Comment(c) => format!("--[{c}]--").into(),
|
||||
Self::LambdaHead(arg) =>
|
||||
tl_cache!(Rc<Variants>: Rc::new(Variants::default().bounded("\\{0b}.")))
|
||||
.units([ttv_fmt(arg, c).await]),
|
||||
.units([arg.print(c).boxed_local().await]),
|
||||
Self::NS(n, b) => tl_cache!(Rc<Variants>: Rc::new(Variants::default().bounded("{0}::{1l}")))
|
||||
.units([n.to_string().into(), b.print(c).boxed_local().await]),
|
||||
Self::Name(n) => format!("{n}").into(),
|
||||
|
||||
Reference in New Issue
Block a user