Macro system done in theory
too afraid to begin debugging, resting for a moment
This commit is contained in:
@@ -6,7 +6,7 @@ macro_rules! clone {
|
||||
$body
|
||||
}
|
||||
);
|
||||
($($n:ident),+) => {
|
||||
$( let $n = $n.clone(); )+
|
||||
($($n:ident $($mut:ident)?),+) => {
|
||||
$( let $($mut)? $n = $n.clone(); )+
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,9 +71,8 @@ impl OrcErr {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Eq for OrcErr {}
|
||||
impl PartialEq for OrcErr {
|
||||
fn eq(&self, other: &Self) -> bool { self.description == other.description }
|
||||
impl PartialEq<Tok<String>> for OrcErr {
|
||||
fn eq(&self, other: &Tok<String>) -> bool { self.description == *other }
|
||||
}
|
||||
impl From<OrcErr> for Vec<OrcErr> {
|
||||
fn from(value: OrcErr) -> Self { vec![value] }
|
||||
@@ -192,16 +191,8 @@ macro_rules! join_ok {
|
||||
(@VALUES) => { Ok(()) };
|
||||
}
|
||||
|
||||
pub fn mk_err(
|
||||
description: Tok<String>,
|
||||
message: impl AsRef<str>,
|
||||
posv: impl IntoIterator<Item = ErrPos>,
|
||||
) -> OrcErr {
|
||||
OrcErr {
|
||||
description,
|
||||
message: Arc::new(message.as_ref().to_string()),
|
||||
positions: posv.into_iter().collect(),
|
||||
}
|
||||
pub fn mk_errv_floating(description: Tok<String>, message: impl AsRef<str>) -> OrcErrv {
|
||||
mk_errv::<Pos>(description, message, [])
|
||||
}
|
||||
|
||||
pub fn mk_errv<I: Into<ErrPos>>(
|
||||
@@ -209,7 +200,12 @@ pub fn mk_errv<I: Into<ErrPos>>(
|
||||
message: impl AsRef<str>,
|
||||
posv: impl IntoIterator<Item = I>,
|
||||
) -> OrcErrv {
|
||||
mk_err(description, message, posv.into_iter().map_into()).into()
|
||||
OrcErr {
|
||||
description,
|
||||
message: Arc::new(message.as_ref().to_string()),
|
||||
positions: posv.into_iter().map_into().collect(),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
pub async fn async_io_err<I: Into<ErrPos>>(
|
||||
|
||||
24
orchid-base/src/iter_utils.rs
Normal file
24
orchid-base/src/iter_utils.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
use std::fmt;
|
||||
|
||||
use itertools::{Itertools, Position};
|
||||
|
||||
pub struct PrintList<'a, I: Iterator<Item = E> + Clone, E: fmt::Display>(pub I, pub &'a str);
|
||||
impl<'a, I: Iterator<Item = E> + Clone, E: fmt::Display> fmt::Display for PrintList<'a, I, E> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
for (pos, item) in self.0.clone().with_position() {
|
||||
match pos {
|
||||
Position::First | Position::Only => write!(f, "{item}")?,
|
||||
Position::Middle => write!(f, ", {item}")?,
|
||||
Position::Last => write!(f, ", {} {item}", self.1)?,
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IteratorPrint: Iterator<Item: fmt::Display> + Clone {
|
||||
fn display<'a>(self, operator: &'a str) -> PrintList<'a, Self, Self::Item> {
|
||||
PrintList(self, operator)
|
||||
}
|
||||
}
|
||||
impl<T: Iterator<Item: fmt::Display> + Clone> IteratorPrint for T {}
|
||||
@@ -12,6 +12,7 @@ pub mod event;
|
||||
pub mod format;
|
||||
pub mod id_store;
|
||||
pub mod interner;
|
||||
pub mod iter_utils;
|
||||
pub mod join;
|
||||
pub mod location;
|
||||
pub mod logging;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// A shorthand for mapping over enums with identical structure. Used for
|
||||
/// A shorthand for mapping over enums with similar structure. Used for
|
||||
/// converting between owned enums and the corresponding API enums that only
|
||||
/// differ in the type of their fields.
|
||||
///
|
||||
@@ -7,7 +7,11 @@
|
||||
/// match_mapping!(self, ThisType => OtherType {
|
||||
/// EmptyVariant,
|
||||
/// TupleVariant(foo => intern(foo), bar.clone()),
|
||||
/// StructVariant{ a.to_api(), b }
|
||||
/// StructVariant{ a.to_api(), b },
|
||||
/// DedicatedConverter(value () convert)
|
||||
/// } {
|
||||
/// ThisType::DimorphicVariant(c) => OtherType::CorrespondingVariant(c.left(), c.right()),
|
||||
/// ThisType::UnexpectedVariant => panic!(),
|
||||
/// })
|
||||
/// ```
|
||||
#[macro_export]
|
||||
|
||||
@@ -19,10 +19,9 @@ trait_set! {
|
||||
pub trait NameIter = Iterator<Item = Tok<String>> + DoubleEndedIterator + ExactSizeIterator;
|
||||
}
|
||||
|
||||
/// A token path which may be empty. [VName] is the non-empty,
|
||||
/// [PathSlice] is the borrowed version
|
||||
/// A token path which may be empty. [VName] is the non-empty version
|
||||
#[derive(Clone, Default, Hash, PartialEq, Eq)]
|
||||
pub struct VPath(pub Vec<Tok<String>>);
|
||||
pub struct VPath(Vec<Tok<String>>);
|
||||
impl VPath {
|
||||
/// Collect segments into a vector
|
||||
pub fn new(items: impl IntoIterator<Item = Tok<String>>) -> Self {
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Range;
|
||||
|
||||
use ordered_float::NotNan;
|
||||
|
||||
use crate::error::{OrcErr, mk_err};
|
||||
use crate::error::{OrcErrv, mk_errv};
|
||||
use crate::interner::Interner;
|
||||
use crate::location::SrcRange;
|
||||
use crate::name::Sym;
|
||||
@@ -55,20 +55,20 @@ pub struct NumError {
|
||||
pub kind: NumErrorKind,
|
||||
}
|
||||
|
||||
pub async fn num_to_err(
|
||||
pub async fn num_to_errv(
|
||||
NumError { kind, range }: NumError,
|
||||
offset: u32,
|
||||
source: &Sym,
|
||||
i: &Interner,
|
||||
) -> OrcErr {
|
||||
mk_err(
|
||||
) -> OrcErrv {
|
||||
mk_errv(
|
||||
i.i("Failed to parse number").await,
|
||||
match kind {
|
||||
NumErrorKind::NaN => "NaN emerged during parsing",
|
||||
NumErrorKind::InvalidDigit => "non-digit character encountered",
|
||||
NumErrorKind::Overflow => "The number being described is too large or too accurate",
|
||||
},
|
||||
[SrcRange::new(offset + range.start as u32..offset + range.end as u32, source).pos().into()],
|
||||
[SrcRange::new(offset + range.start as u32..offset + range.end as u32, source)],
|
||||
)
|
||||
}
|
||||
|
||||
@@ -92,11 +92,11 @@ pub fn parse_num(string: &str) -> Result<Numeric, NumError> {
|
||||
match base_s.split_once('.') {
|
||||
None => {
|
||||
let base = int_parse(base_s, radix, pos)?;
|
||||
if let Ok(pos_exp) = u32::try_from(exponent) {
|
||||
if let Some(radical) = u64::from(radix).checked_pow(pos_exp) {
|
||||
let num = base.checked_mul(radical).and_then(|m| m.try_into().ok()).ok_or(overflow_e)?;
|
||||
return Ok(Numeric::Int(num));
|
||||
}
|
||||
if let Ok(pos_exp) = u32::try_from(exponent)
|
||||
&& let Some(radical) = u64::from(radix).checked_pow(pos_exp)
|
||||
{
|
||||
let num = base.checked_mul(radical).and_then(|m| m.try_into().ok()).ok_or(overflow_e)?;
|
||||
return Ok(Numeric::Int(num));
|
||||
}
|
||||
let f = (base as f64) * (radix as f64).powi(exponent);
|
||||
let err = NumError { range: 0..string.len(), kind: NumErrorKind::NaN };
|
||||
|
||||
@@ -7,11 +7,11 @@ use futures::future::join_all;
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::api;
|
||||
use crate::error::{OrcErrv, OrcRes, Reporter, mk_err, mk_errv};
|
||||
use crate::error::{OrcErrv, OrcRes, Reporter, mk_errv};
|
||||
use crate::format::{FmtCtx, FmtUnit, Format, fmt};
|
||||
use crate::interner::{Interner, Tok};
|
||||
use crate::location::SrcRange;
|
||||
use crate::name::{NameLike, Sym, VName, VPath};
|
||||
use crate::name::{Sym, VName, VPath};
|
||||
use crate::tree::{ExprRepr, ExtraTok, Paren, TokTree, Token, ttv_fmt, ttv_range};
|
||||
|
||||
pub trait ParseCtx {
|
||||
@@ -237,10 +237,10 @@ pub async fn parse_multiname<'a, A: ExprRepr, X: ExtraTok>(
|
||||
match &tt.tok {
|
||||
Token::NS(ns, body) => {
|
||||
if !ns.starts_with(name_start) {
|
||||
ctx.rep().report(mk_err(
|
||||
ctx.rep().report(mk_errv(
|
||||
ctx.i().i("Unexpected name prefix").await,
|
||||
"Only names can precede ::",
|
||||
[ttpos.into()],
|
||||
[ttpos],
|
||||
))
|
||||
};
|
||||
let out = Box::pin(rec(body, ctx)).await?;
|
||||
|
||||
Reference in New Issue
Block a user