pratt_gen_core/
primitive.rs1use once_cell::sync::Lazy;
2use crate::*;
3
4macro_rules! impl_i {($($int: ty)*) => {$(
5 impl<'a> ParserImpl<'a> for $int {
6 fn parser_impl(
7 source: Source<'a>,
8 out_arena: &'a Arena,
9 err_arena: &'a Arena,
10 precedence: u16,
11 ) -> Result<(Self, Source<'a>), Error<'a>> {
12 let _ = out_arena;
13 let _ = precedence;
14 let mut by = 0;
15 if source[..].starts_with("-") { by += 1; }
16 for c in source[by..].chars() {
17 if !c.is_ascii_digit() { break }
18 by += c.len_utf8();
19 }
20 match source[..by].parse::<$int>() {
21 Ok(out) => Ok((out, source.proceed(by))),
22 Err(_) => Err(Error::Mismatch {
23 range: (source.split, source.split + by),
24 token: stringify!($int),
25 piece: unsafe { err_arena.alloc_str(&source[..source[..].chars().next().map(|x| x.len_utf8()).unwrap_or(0)]) }
26 })
27 }
28 }
29 })*
30};}
31
32impl_i!{i8 i16 i32 i64 i128}
33
34macro_rules! impl_u {($($int: ty)*) => {$(
35 impl<'a> ParserImpl<'a> for $int {
36 fn parser_impl(
37 source: Source<'a>,
38 out_arena: &'a Arena,
39 err_arena: &'a Arena,
40 precedence: u16,
41 ) -> Result<(Self, Source<'a>), Error<'a>> {
42 let _ = out_arena;
43 let _ = precedence;
44 let mut by = 0;
45 for c in source[by..].chars() {
46 if !c.is_ascii_digit() { break }
47 by += c.len_utf8();
48 }
49 match source[..by].parse::<$int>() {
50 Ok(out) => Ok((out, source.proceed(by))),
51 Err(_) => Err(Error::Mismatch {
52 range: (source.split, source.split + by),
53 token: stringify!($int),
54 piece: unsafe { err_arena.alloc_str(&source[..source[..].chars().next().map(|x| x.len_utf8()).unwrap_or(0)]) }
55 })
56 }
57 }
58 })*
59};}
60
61impl_u!{u8 u16 u32 u64 u128}
62
63macro_rules! impl_f {($($flt: ty)*) => {$(
64 impl<'a> ParserImpl<'a> for $flt {
65 fn parser_impl(
66 source: Source<'a>,
67 out_arena: &'a Arena,
68 err_arena: &'a Arena,
69 precedence: u16,
70 ) -> Result<(Self, Source<'a>), Error<'a>> {
71 let _ = out_arena;
72 let _ = precedence;
73 let mut by = 0;
74 let mut dot = false;
75 if source[..].starts_with("-") { by += 1; }
76 for c in source[by..].chars() {
77 if c == '.' && !dot {
78 dot = true;
79 by += c.len_utf8();
80 continue;
81 }
82 if !c.is_ascii_digit() { break }
83 by += c.len_utf8();
84 }
85 match source[..by].parse::<$flt>() {
86 Ok(out) => Ok((out, source.proceed(by))),
87 Err(_) => Err(Error::Mismatch {
88 range: (source.split, source.split + by),
89 token: stringify!($flt),
90 piece: unsafe { err_arena.alloc_str(&source[..source[..].chars().next().map(|x| x.len_utf8()).unwrap_or(0)]) }
91 })
92 }
93 }
94 })*
95};}
96
97impl_f!{f32 f64}
98
99#[derive(Debug, Clone, Copy)]
100pub struct Ident<'a>(pub &'a str);
101
102impl<'a> Ident<'a> { pub fn to_str(&self) -> &'a str { self.0 } }
103
104impl<'a> ParserImpl<'a> for Ident<'a> {
105 fn parser_impl(
106 source: Source<'a>,
107 out_arena: &'a Arena,
108 err_arena: &'a Arena,
109 _: u16,
110 ) -> Result<(Self, Source<'a>), Error<'a>> {
111 let mut len = 0;
112 let mut char_len = 0;
113 for c in source[..].chars() {
114 if c.is_ascii_alphanumeric() {
115 len += c.len_utf8();
116 } else {
117 char_len = c.len_utf8();
118 break;
119 }
120 }
121 unsafe {if len == 0 {
122 Err(Error::Mismatch {
123 range: (source.split, source.split + len),
124 token: "",
125 piece: err_arena.alloc_str(&source[..char_len])
126 })
127 } else {
128 let ident = out_arena.alloc_str(&source[..len]);
129 Ok((Ident(ident), source.proceed(len)))
130 } }
131 }
132}
133
134impl<'a> ParserImpl<'a> for &'a str {
135 fn parser_impl(
136 source: Source<'a>,
137 out_arena: &'a Arena,
138 err_arena: &'a Arena,
139 _: u16,
140 ) -> Result<(Self, Source<'a>), Error<'a>> {
141 use regex::Regex;
142 static REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(
143 r#"^"([^"\\]|\\\\|\\")*""#
144 ).unwrap());
145 let Some(by) = REGEX.shortest_match(&source[..]) else {
146 Err(Error::Mismatch {
147 range: (source.split, source.split+2),
148 token: "<str>",
149 piece: unsafe{err_arena.alloc_str(&source[..source[..].chars().next().map(|x| x.len_utf8()).unwrap_or(0)])}
150 })?
151 };
152 let s = unsafe{ out_arena.alloc_str(&source[1..by-1]) };
153 Ok((s, source.proceed(by)))
154 }
155}