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