1use super::{PResult, PResultExt, Parse, ParseError, Parser, no_eof, pat::Prec as PPrec};
4use cl_ast::{
5 types::{Literal, Path},
6 *,
7};
8use cl_token::{TKind, Token};
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
12pub enum Prec {
13 Min,
14 Do,
16 Body,
18 Assign,
20 Make,
22 Tuple,
24 Logical,
26 LogOr,
28 LogAnd,
30 Compare,
32 Range,
34 Binary,
36 Shift,
38 Factor,
40 Term,
42 Unary,
44 Project,
46 Extend,
48 Max,
49}
50
51impl Prec {
52 pub const MIN: usize = Prec::Min.value();
53
54 pub const fn value(self) -> usize {
55 self as usize * 2
56 }
57
58 pub const fn prev(self) -> usize {
59 match self {
60 Self::Assign => self.value() + 1,
61 _ => self.value(),
62 }
63 }
64
65 pub const fn next(self) -> usize {
66 match self {
67 Self::Assign => self.value(),
68 _ => self.value() + 1,
69 }
70 }
71}
72
73#[derive(Clone, Copy, Debug, PartialEq, Eq)]
75pub enum Ps {
76 Id, Mid, Underscore, Lit, Use, Bind, DocInner, DocOuter, For, Lambda0, Lambda, DoubleRef, Make, Match, ImplicitDo, Ellipsis, End, Op(Op), }
95
96fn from_prefix(token: &Token) -> PResult<(Ps, Prec)> {
99 Ok(match token.kind {
100 TKind::Do => (Ps::Op(Op::Do), Prec::Do),
101 TKind::Semi => (Ps::End, Prec::Body),
102
103 TKind::InDoc => (Ps::DocInner, Prec::Min),
104 TKind::OutDoc => (Ps::DocOuter, Prec::Max),
105 TKind::HashBang => (Ps::Op(Op::MetaInner), Prec::Min),
106 TKind::Hash => (Ps::Op(Op::MetaOuter), Prec::Max),
107
108 TKind::Identifier | TKind::ColonColon => (Ps::Id, Prec::Max),
109 TKind::Underscore => (Ps::Underscore, Prec::Max),
110 TKind::Dollar => (Ps::Mid, Prec::Max),
111 TKind::True | TKind::False | TKind::Character | TKind::Integer | TKind::String => {
112 (Ps::Lit, Prec::Max)
113 }
114 TKind::Use => (Ps::Use, Prec::Max),
115
116 TKind::Pub => (Ps::Op(Op::Pub), Prec::Max),
117 TKind::Const => (Ps::Op(Op::Const), Prec::Max),
118 TKind::Static => (Ps::Op(Op::Static), Prec::Max),
119 TKind::For => (Ps::For, Prec::Max),
120 TKind::Match => (Ps::Match, Prec::Max),
121 TKind::Macro => (Ps::Op(Op::Macro), Prec::Assign),
122
123 TKind::Fn
124 | TKind::Mod
125 | TKind::Impl
126 | TKind::Let
127 | TKind::Type
128 | TKind::Struct
129 | TKind::Enum => (Ps::Bind, Prec::Max),
130
131 TKind::Loop => (Ps::Op(Op::Loop), Prec::Body),
132 TKind::If => (Ps::Op(Op::If), Prec::Body),
133 TKind::While => (Ps::Op(Op::While), Prec::Body),
134 TKind::Defer => (Ps::Op(Op::Defer), Prec::Body),
135 TKind::Break => (Ps::Op(Op::Break), Prec::Body),
136 TKind::Return => (Ps::Op(Op::Return), Prec::Body),
137 TKind::Continue => (Ps::Op(Op::Continue), Prec::Max),
138
139 TKind::LCurly => (Ps::Op(Op::Block), Prec::Min),
140 TKind::RCurly => (Ps::End, Prec::Do),
141 TKind::LBrack => (Ps::Op(Op::Array), Prec::Tuple),
142 TKind::RBrack => (Ps::End, Prec::Tuple),
143 TKind::LParen => (Ps::Op(Op::Group), Prec::Min),
144 TKind::RParen => (Ps::End, Prec::Tuple),
145 TKind::Grave => (Ps::Op(Op::Quote), Prec::Min),
146 TKind::Amp => (Ps::Op(Op::Refer), Prec::Unary),
147 TKind::AmpAmp => (Ps::DoubleRef, Prec::Unary),
148 TKind::Bang => (Ps::Op(Op::Not), Prec::Unary),
149 TKind::BangBang => (Ps::Op(Op::Identity), Prec::Unary),
150 TKind::Bar => (Ps::Lambda, Prec::Body),
151 TKind::BarBar => (Ps::Lambda0, Prec::Body),
152 TKind::DotDot => (Ps::Op(Op::RangeEx), Prec::Range),
153 TKind::DotDotDot => (Ps::Ellipsis, Prec::Max),
154 TKind::DotDotEq => (Ps::Op(Op::RangeIn), Prec::Range),
155 TKind::Minus => (Ps::Op(Op::Neg), Prec::Unary),
156 TKind::Plus => (Ps::Op(Op::Identity), Prec::Unary),
157 TKind::Star => (Ps::Op(Op::Deref), Prec::Unary),
158
159 kind => Err(ParseError::NotPrefix(kind, token.span))?,
160 })
161}
162
163const fn from_infix(token: &Token) -> PResult<(Ps, Prec)> {
166 Ok(match token.kind {
167 TKind::Semi => (Ps::Op(Op::Do), Prec::Do), TKind::In => (Ps::Op(Op::Do), Prec::Do),
169
170 TKind::Eq => (Ps::Op(Op::Set), Prec::Assign),
171 TKind::StarEq => (Ps::Op(Op::MulSet), Prec::Assign),
172 TKind::SlashEq => (Ps::Op(Op::DivSet), Prec::Assign),
173 TKind::RemEq => (Ps::Op(Op::RemSet), Prec::Assign),
174 TKind::PlusEq => (Ps::Op(Op::AddSet), Prec::Assign),
175 TKind::MinusEq => (Ps::Op(Op::SubSet), Prec::Assign),
176 TKind::LtLtEq => (Ps::Op(Op::ShlSet), Prec::Assign),
177 TKind::GtGtEq => (Ps::Op(Op::ShrSet), Prec::Assign),
178 TKind::AmpEq => (Ps::Op(Op::AndSet), Prec::Assign),
179 TKind::XorEq => (Ps::Op(Op::XorSet), Prec::Assign),
180 TKind::BarEq => (Ps::Op(Op::OrSet), Prec::Assign),
181 TKind::Comma => (Ps::Op(Op::Tuple), Prec::Tuple),
182 TKind::LCurly => (Ps::Make, Prec::Make),
183 TKind::XorXor => (Ps::Op(Op::LogXor), Prec::Logical),
184 TKind::BarBar => (Ps::Op(Op::LogOr), Prec::LogOr),
185 TKind::AmpAmp => (Ps::Op(Op::LogAnd), Prec::LogAnd),
186 TKind::Lt => (Ps::Op(Op::Lt), Prec::Compare),
187 TKind::LtEq => (Ps::Op(Op::Leq), Prec::Compare),
188 TKind::EqEq => (Ps::Op(Op::Eq), Prec::Compare),
189 TKind::BangEq => (Ps::Op(Op::Neq), Prec::Compare),
190 TKind::GtEq => (Ps::Op(Op::Geq), Prec::Compare),
191 TKind::Gt => (Ps::Op(Op::Gt), Prec::Compare),
192 TKind::DotDot => (Ps::Op(Op::RangeEx), Prec::Range),
193 TKind::DotDotEq => (Ps::Op(Op::RangeIn), Prec::Range),
194 TKind::Amp => (Ps::Op(Op::And), Prec::Binary),
195 TKind::Xor => (Ps::Op(Op::Xor), Prec::Binary),
196 TKind::Bar => (Ps::Op(Op::Or), Prec::Binary),
197 TKind::LtLt => (Ps::Op(Op::Shl), Prec::Shift),
198 TKind::GtGt => (Ps::Op(Op::Shr), Prec::Shift),
199 TKind::Plus => (Ps::Op(Op::Add), Prec::Factor),
200 TKind::Minus => (Ps::Op(Op::Sub), Prec::Factor),
201 TKind::Star => (Ps::Op(Op::Mul), Prec::Term),
202 TKind::Slash => (Ps::Op(Op::Div), Prec::Term),
203 TKind::Rem => (Ps::Op(Op::Rem), Prec::Term),
204
205 TKind::Question => (Ps::Op(Op::Try), Prec::Unary),
206 TKind::Dot => (Ps::Op(Op::Dot), Prec::Project),
207 TKind::LBrack => (Ps::Op(Op::Index), Prec::Project),
208 TKind::LParen => (Ps::Op(Op::Call), Prec::Extend),
209
210 TKind::RParen | TKind::RBrack | TKind::RCurly | TKind::Grave => (Ps::End, Prec::Max),
211 TKind::As => (Ps::Op(Op::As), Prec::Unary),
212 _ => (Ps::ImplicitDo, Prec::Do),
213 })
214}
215
216impl<'t> Parse<'t> for Expr {
217 type Prec = usize;
218
219 fn parse(p: &mut Parser<'t>, level: usize) -> PResult<Self> {
223 const MIN: usize = Prec::MIN;
224
225 let tok @ &Token { kind, span, .. } = p.peek()?;
227 let (op, prec) = from_prefix(tok)?;
228 no_eof(move || {
229 let mut head = match op {
230 Ps::End if level <= prec.next() => Expr::Omitted,
235 Ps::End => Err(ParseError::NotPrefix(kind, span))?,
236
237 Ps::Id => Expr::Id(p.parse(())?),
238 Ps::Mid => Expr::MetId(p.consume().next()?.lexeme.to_string().as_str().into()),
239 Ps::Underscore => {
240 p.consume();
241 Expr::Id(Path { parts: vec!["_".into()] })
242 }
243 Ps::Lit => Expr::Lit(p.parse(())?),
244 Ps::Use => Expr::Use(p.consume().parse(())?),
245 Ps::Bind => Expr::Bind(p.parse(())?),
246 Ps::For => parse_for(p, ())?,
247 Ps::Match => Expr::Match(p.parse(())?),
248 Ps::Lambda | Ps::Lambda0 => {
249 p.split()?; let args = p
252 .opt(PPrec::Tuple, TKind::Bar)?
253 .map(|At(pat, span): At<Pat>| pat.to_tuple(span).at(span))
254 .unwrap_or(At(Pat::Op(PatOp::Tuple, vec![]), span.merge(p.span())));
255
256 let rety = p
257 .opt_if(PPrec::Fn, TKind::Arrow)?
258 .unwrap_or(Pat::Ignore.at(p.span()));
259
260 Expr::Bind(Box::new(Bind(
261 BindOp::Fn,
262 vec![],
263 Pat::Op(PatOp::Fn, vec![args, rety]).at(span.merge(p.span())),
264 vec![p.parse(prec.next())?],
265 )))
266 }
267 Ps::DocOuter | Ps::DocInner => {
268 let comment = Literal::Str(p.take_lexeme()?.string().unwrap());
269 let comment = Expr::Lit(comment).at(span);
270 let next = match p.peek().allow_eof()? {
272 Some(_) => p.parse(prec.next())?,
273 None => Expr::Omitted.at(span),
274 };
275 Expr::Op(
276 match op {
277 Ps::DocOuter => Op::MetaOuter,
278 _ => Op::MetaInner,
279 },
280 vec![comment, next],
281 )
282 }
283 Ps::Ellipsis => p.consume().then(Expr::Omitted),
284 Ps::Op(op @ (Op::MetaOuter | Op::MetaInner)) => {
285 if p.consume().expect(TKind::LBrack).is_err() {
287 return p.parse(level);
288 }
289 let meta = p
290 .opt(MIN, TKind::RBrack)?
291 .unwrap_or_else(|| Expr::Omitted.at(span));
292 Expr::Op(op, vec![meta, p.parse(prec.next())?])
293 }
294 Ps::Op(op @ (Op::Block | Op::Quote)) => {
295 Expr::Op(op, p.consume().opt(MIN, kind.flip())?.into_iter().collect())
296 }
297 Ps::Op(Op::Array) => parse_array(p)?,
298 Ps::Op(Op::Group) => match p.consume().opt(MIN, kind.flip())? {
299 Some(value) => Expr::Op(Op::Group, vec![value]),
300 None => Expr::Op(Op::Tuple, vec![]),
301 },
302 Ps::Op(Op::Continue) => p.consume().then(Expr::Op(Op::Continue, vec![])),
303 Ps::Op(op @ (Op::If | Op::While)) => {
304 p.consume();
305 let exprs = vec![
306 p.parse(Prec::Logical.value())?,
308 p.parse(prec.next())?,
309 match p.next_if(TKind::Else).allow_eof()? {
310 Some(Ok(_)) => p.parse(prec.next())?,
311 _ => Expr::Omitted.at(span.merge(p.span())),
312 },
313 ];
314 Expr::Op(op, exprs)
315 }
316 Ps::DoubleRef => {
317 p.split()?;
318 Expr::Op(Op::Refer, vec![p.parse(prec.next())?])
319 }
320
321 Ps::Op(op) => Expr::Op(op, vec![p.consume().parse(prec.next())?]),
322 _ => unimplemented!("prefix {op:?}"),
323 };
324
325 while let Ok(Some(tok @ &Token { kind, .. })) = p.peek().allow_eof()
327 && let Ok((op, prec)) = from_infix(tok)
328 && level <= prec.prev()
329 && op != Ps::End
330 {
331 let span = span.merge(p.span());
332
333 head = match op {
334 Ps::Make if let Expr::Id(_) | Expr::MetId(_) = head => {
336 Expr::Make(Box::new(Make(
337 head.at(span),
338 p.consume().list(vec![], (), TKind::Comma, TKind::RCurly)?,
339 )))
340 }
341 Ps::Make => break,
342 Ps::ImplicitDo if p.can_do => head.and_do(span, p.parse(prec.next())?),
344 Ps::ImplicitDo => break,
345 Ps::Op(Op::Do) => head.and_do(
347 span,
348 match p.consume().peek().allow_eof()? {
349 Some(_) => p.parse(prec.next())?,
350 None => At(Expr::Omitted, p.span()),
351 },
352 ),
353 Ps::Op(Op::Call | Op::Index) if p.can_do => break,
355 Ps::Op(Op::Index) => Expr::Op(
356 Op::Index,
357 p.consume()
358 .list(vec![head.at(span)], 0, TKind::Comma, TKind::RBrack)?,
359 ),
360 Ps::Op(Op::Call) => {
361 let head = head.at(span);
362 let args = match p.consume().opt::<At<Expr>>(0, TKind::RParen)? {
363 None => Expr::Op(Op::Tuple, vec![]).at(span),
364 Some(At(expr, span)) => expr.to_tuple(span).at(span),
365 };
366 Expr::Op(Op::Call, vec![head, args])
367 }
368 Ps::Op(op @ Op::Tuple) => Expr::Op(
369 op,
370 p.consume()
371 .list_bare(vec![head.at(span)], prec.next(), kind)?,
372 ) .deomit(),
374 Ps::Op(op @ Op::Try) => {
375 p.consume();
376 Expr::Op(op, vec![head.at(span)])
377 }
378 Ps::Op(op) => {
379 Expr::Op(op, vec![head.at(span), p.consume().parse(prec.next())?])
380 }
381 _ => Err(ParseError::NotInfix(kind, span))?,
382 }
383 }
384
385 Ok(head)
386 })
387 }
388}
389
390fn parse_array(p: &mut Parser<'_>) -> PResult<Expr> {
392 if p.consume().peek()?.kind == TKind::RBrack {
393 p.consume();
394 return Ok(Expr::Op(Op::Array, vec![]));
395 }
396
397 let prec = Prec::Tuple;
398 let item = p.parse(prec.value())?;
399 let repeat = p.opt_if(prec.next(), TKind::Semi)?;
400 p.expect(TKind::RBrack)?;
401
402 Ok(match (repeat, item) {
403 (Some(repeat), item) => Expr::Op(Op::ArRep, vec![item, repeat]),
404 (None, At(Expr::Op(Op::Tuple, items), _)) => Expr::Op(Op::Array, items),
405 (None, item) => Expr::Op(Op::Array, vec![item]),
406 })
407}
408
409impl<'t> Parse<'t> for Match {
417 type Prec = ();
418
419 fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> {
420 let scrutinee = p.consume().parse(Prec::Tuple.value())?;
421 let mut arms = vec![];
422
423 p.expect(TKind::LCurly)?;
424 while p.next_if(TKind::RCurly)?.is_err() {
425 arms.push(p.parse(())?);
426 if p.next_if(TKind::Semi)?.is_err() && !p.can_do {
427 break;
428 }
429 }
430
431 Ok(Self(scrutinee, arms))
432 }
433}
434
435impl<'t> Parse<'t> for MatchArm {
436 type Prec = ();
437
438 fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self>
439 where Self: Sized {
440 let pat = p.parse(PPrec::Min)?;
448 p.expect(TKind::FatArrow)?;
449 let body = p.parse(Prec::Body.value())?;
450
451 Ok(Self(pat, body))
452 }
453}
454
455fn parse_for(p: &mut Parser<'_>, _level: ()) -> PResult<Expr> {
457 let pat = p.consume().parse(PPrec::Tuple)?;
459 let iter: At<Expr> = p.expect(TKind::In)?.parse(Prec::Logical.next())?;
461 let pass: At<Expr> = p.parse(Prec::Body.next())?;
463 let pspan = pass.1;
464 let fail = match p.next_if(TKind::Else).allow_eof()? {
466 Some(Ok(_)) => p.parse(Prec::Body.next())?,
467 _ => Expr::Omitted.at(pspan),
468 };
469 Ok(Expr::Bind(Box::new(Bind(
482 BindOp::For,
483 vec![],
484 pat,
485 vec![iter, pass, fail],
486 ))))
487}
488
489#[rustfmt::skip]
492#[allow(clippy::type_complexity)]
493fn from_bind(p: &mut Parser<'_>) -> PResult<(BindOp, PPrec, Option<TKind>, Option<Prec>, Option<Prec>)> {
494 let bk = match p.peek()?.kind {
495 TKind::Let => (BindOp::Let, PPrec::Tuple, Some(TKind::Eq), Some(Prec::Body), Some(Prec::Body)),
497 TKind::Type => (BindOp::Type, PPrec::Alt, Some(TKind::Eq), Some(Prec::Body), None),
498 TKind::Struct => (BindOp::Struct, PPrec::Tuple, None, None, None),
499 TKind::Enum => (BindOp::Enum, PPrec::Tuple, None, None, None),
500 TKind::Fn => (BindOp::Fn, PPrec::Fn, None, Some(Prec::Body), None),
501 TKind::Mod => (BindOp::Mod, PPrec::Max, None, Some(Prec::Body), None),
502 TKind::Impl => (BindOp::Impl, PPrec::Fn, None, Some(Prec::Body), None),
503 other => return Err(ParseError::NotBind(other, p.span()))
504 };
505
506 p.consume();
507 Ok(bk)
508}
509
510impl<'t> Parse<'t> for Bind {
511 type Prec = ();
512
513 fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> {
514 let (bind, patp, equals, bodyp, failp) = from_bind(p)?;
516
517 let generics = match p.next_if(TKind::Lt)? {
519 Ok(_) => p.list(vec![], (), TKind::Comma, TKind::Gt)?,
520 Err(_) => vec![],
521 };
522
523 let pat = p.parse(patp)?;
525
526 let Some(bodyp) = bodyp else {
527 return Ok(Self(bind, generics, pat, vec![]));
528 };
529
530 if let Some(equals) = equals {
532 if p.next_if(equals).allow_eof()?.is_none_or(|v| v.is_err()) {
533 return Ok(Self(bind, generics, pat, vec![]));
534 }
535 } else {
536 p.next_if(TKind::Eq).allow_eof()?;
538 }
539
540 let body = p.parse(bodyp.value())?;
542
543 let Some(failp) = failp else {
544 return Ok(Self(bind, generics, pat, vec![body]));
545 };
546
547 if p.next_if(TKind::Else)
549 .allow_eof()?
550 .is_none_or(|v| v.is_err())
551 {
552 return Ok(Self(bind, generics, pat, vec![body]));
553 }
554
555 let fail = p.parse(failp.value())?;
556
557 Ok(Self(bind, generics, pat, vec![body, fail]))
558 }
559}
560
561impl<'t> Parse<'t> for MakeArm {
562 type Prec = ();
563
564 fn parse(p: &mut Parser<'t>, _level: ()) -> PResult<Self> {
565 let name = p
566 .next_if(TKind::Identifier)?
567 .map_err(|tk| ParseError::Expected(TKind::Identifier, tk, p.span()))?;
568 Ok(MakeArm(
569 name.lexeme
570 .str()
571 .expect("Identifier should have String")
572 .into(),
573 p.opt_if(Prec::Tuple.next(), TKind::Colon)?,
574 ))
575 }
576}