1use std::{fmt::{Debug, Display}, marker::PhantomData, ops::Deref, sync::atomic::AtomicU16};
2
3mod source;
4mod arena;
5mod token;
6mod space;
7mod span;
8mod primitive;
9pub use source::*;
10pub use arena::*;
11pub use token::*;
12pub use space::*;
13pub use span::*;
14pub use primitive::*;
15
16static COUNTER: AtomicU16 = AtomicU16::new(0);
17
18#[derive(Debug, Clone)]
19pub enum Error<'a> {
20 Mismatch {
21 range: (usize, usize),
22 token: &'static str,
23 piece: &'a str,
24 },
25 Precedence,
26 List(&'a List<'a, Error<'a>>),
27}
28
29impl<'a> Display for Error<'a> {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 use Error::*;
32 match self {
33 Precedence => {write!(f, "")}
34 Mismatch { range, token, piece } => {
35 writeln!(f, "{}..{} expected: {token:?}, found: {piece:?}", range.0, range.1)
36 }
37 List(list) => {
38 writeln!(f, "{list}")
39 }
40 }
41 }
42}
43
44#[derive(Clone, Copy)]
45pub enum List<'a, T> {
46 Null,
47 Some(&'a List<'a, T>, T)
48}
49
50impl<'a, T> List<'a, T> {
51 pub fn new() -> Self {
52 List::Null
53 }
54 pub fn push(self, arena: &'a Arena, value: T) -> Self {
55 let list = unsafe { arena.alloc(self) };
56 List::Some(list, value)
57 }
58}
59
60impl<'a, T: Debug> Debug for List<'a, T> {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 match self {
63 List::Null => write!(f, ""),
64 List::Some(List::Null, x) => write!(f, "{x:?}"),
65 List::Some(list, x) => write!(f, "{list:?}, {x:?}"),
66 }
67 }
68}
69
70impl<'a, T: Display> Display for List<'a, T> {
71 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72 match self {
73 List::Null => write!(f, ""),
74 List::Some(List::Null, x) => write!(f, "{x}"),
75 List::Some(list, x) => write!(f, "{list}{x}"),
76 }
77 }
78}
79
80pub trait ParserImpl<'a>: Sized + Copy {
81 fn num() -> u16 {
82 use once_cell::sync::Lazy;
83 use std::sync::atomic::Ordering::SeqCst;
84 static NUM: Lazy<u16> = Lazy::new(|| COUNTER.fetch_add(1, SeqCst));
85 *NUM.deref()
86 }
87 fn parser_impl(
88 source: Source<'a>,
89 out_arena: &'a Arena,
90 err_arena: &'a Arena,
91 precedence: u16,
92 ) -> Result<(Self, Source<'a>), Error<'a>>;
93}
94
95impl<'a, X: ParserImpl<'a>> ParserImpl<'a> for &'a X {
96 fn parser_impl(
97 source: Source<'a>,
98 out_arena: &'a Arena,
99 err_arena: &'a Arena,
100 precedence: u16,
101 ) -> Result<(Self, Source<'a>), Error<'a>> {
102 stacker::maybe_grow(32*1024, 4*1024*1024, || {
103 let (out, source) = X::parser_impl(source, out_arena, err_arena, precedence)?;
104 unsafe { Ok((out_arena.alloc(out), source)) }
105 })
106 }
107}
108
109pub fn parse<'a, X: ParserImpl<'a>>(
110 source: Source<'a>,
111 out_arena: &'a Arena,
112 err_arena: &'a Arena
113) -> Result<X, Error<'a>> {
114 match X::parser_impl(source, out_arena, err_arena, 0) {
115 Ok((out, _)) => Ok(out),
116 Err(err) => Err(err),
117 }
118}