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, ImplicitDo, Ellipsis, End, Op(Op), }
91
92fn from_prefix(token: &Token) -> PResult<(Ps, Prec)> {
95 Ok(match token.kind {
96 TKind::InDoc => (Ps::DocInner, Prec::Min),
97 TKind::OutDoc => (Ps::DocOuter, Prec::Max),
98 TKind::Do => (Ps::Op(Op::Do), Prec::Do),
99 TKind::Semi => (Ps::End, Prec::Body),
100
101 TKind::Identifier | TKind::ColonColon => (Ps::Id, Prec::Max),
102 TKind::Dollar => (Ps::Mid, Prec::Max),
103 TKind::True | TKind::False | TKind::Character | TKind::Integer | TKind::String => {
104 (Ps::Lit, Prec::Max)
105 }
106 TKind::Use => (Ps::Use, Prec::Max),
107
108 TKind::Pub => (Ps::Op(Op::Pub), Prec::Max),
109 TKind::Const => (Ps::Op(Op::Const), Prec::Max),
110 TKind::Static => (Ps::Op(Op::Static), Prec::Max),
111 TKind::For => (Ps::For, Prec::Max),
112 TKind::Match => (Ps::Match, Prec::Max),
113 TKind::Macro => (Ps::Op(Op::Macro), Prec::Assign),
114
115 TKind::Fn
116 | TKind::Mod
117 | TKind::Impl
118 | TKind::Let
119 | TKind::Type
120 | TKind::Struct
121 | TKind::Enum => (Ps::Def, Prec::Max),
122
123 TKind::Loop => (Ps::Op(Op::Loop), Prec::Body),
124 TKind::If => (Ps::Op(Op::If), Prec::Body),
125 TKind::While => (Ps::Op(Op::While), Prec::Body),
126 TKind::Defer => (Ps::Op(Op::Defer), Prec::Body),
127 TKind::Break => (Ps::Op(Op::Break), Prec::Body),
128 TKind::Return => (Ps::Op(Op::Return), Prec::Body),
129 TKind::Continue => (Ps::Op(Op::Continue), Prec::Max),
130
131 TKind::LCurly => (Ps::Op(Op::Block), Prec::Min),
132 TKind::RCurly => (Ps::End, Prec::Do),
133 TKind::LBrack => (Ps::Op(Op::Array), Prec::Tuple),
134 TKind::RBrack => (Ps::End, Prec::Tuple),
135 TKind::LParen => (Ps::Op(Op::Group), Prec::Min),
136 TKind::RParen => (Ps::End, Prec::Tuple),
137 TKind::Amp => (Ps::Op(Op::Refer), Prec::Unary),
138 TKind::AmpAmp => (Ps::DoubleRef, Prec::Unary),
139 TKind::Bang => (Ps::Op(Op::Not), Prec::Unary),
140 TKind::BangBang => (Ps::Op(Op::Identity), Prec::Unary),
141 TKind::Bar => (Ps::Lambda, Prec::Body),
142 TKind::BarBar => (Ps::Lambda0, Prec::Body),
143 TKind::DotDot => (Ps::Op(Op::RangeEx), Prec::Range),
144 TKind::DotDotDot => (Ps::Ellipsis, Prec::Max),
145 TKind::DotDotEq => (Ps::Op(Op::RangeIn), Prec::Range),
146 TKind::Minus => (Ps::Op(Op::Neg), Prec::Unary),
147 TKind::Plus => (Ps::Op(Op::Identity), Prec::Unary),
148 TKind::Star => (Ps::Op(Op::Deref), Prec::Unary),
149 TKind::Hash => (Ps::Op(Op::MetaOuter), Prec::Max),
150 TKind::HashBang => (Ps::Op(Op::MetaInner), Prec::Max),
151
152 kind => Err(ParseError::NotPrefix(kind, token.span))?,
153 })
154}
155
156const fn from_infix(token: &Token) -> PResult<(Ps, Prec)> {
159 Ok(match token.kind {
160 TKind::Semi => (Ps::Op(Op::Do), Prec::Do), TKind::In => (Ps::Op(Op::Do), Prec::Do),
162
163 TKind::Eq => (Ps::Op(Op::Set), Prec::Assign),
164 TKind::StarEq => (Ps::Op(Op::MulSet), Prec::Assign),
165 TKind::SlashEq => (Ps::Op(Op::DivSet), Prec::Assign),
166 TKind::RemEq => (Ps::Op(Op::RemSet), Prec::Assign),
167 TKind::PlusEq => (Ps::Op(Op::AddSet), Prec::Assign),
168 TKind::MinusEq => (Ps::Op(Op::SubSet), Prec::Assign),
169 TKind::LtLtEq => (Ps::Op(Op::ShlSet), Prec::Assign),
170 TKind::GtGtEq => (Ps::Op(Op::ShrSet), Prec::Assign),
171 TKind::AmpEq => (Ps::Op(Op::AndSet), Prec::Assign),
172 TKind::XorEq => (Ps::Op(Op::XorSet), Prec::Assign),
173 TKind::BarEq => (Ps::Op(Op::OrSet), Prec::Assign),
174 TKind::Comma => (Ps::Op(Op::Tuple), Prec::Tuple),
175 TKind::LCurly => (Ps::Make, Prec::Make),
176 TKind::XorXor => (Ps::Op(Op::LogXor), Prec::Logical),
177 TKind::BarBar => (Ps::Op(Op::LogOr), Prec::LogOr),
178 TKind::AmpAmp => (Ps::Op(Op::LogAnd), Prec::LogAnd),
179 TKind::Lt => (Ps::Op(Op::Lt), Prec::Compare),
180 TKind::LtEq => (Ps::Op(Op::Leq), Prec::Compare),
181 TKind::EqEq => (Ps::Op(Op::Eq), Prec::Compare),
182 TKind::BangEq => (Ps::Op(Op::Neq), Prec::Compare),
183 TKind::GtEq => (Ps::Op(Op::Geq), Prec::Compare),
184 TKind::Gt => (Ps::Op(Op::Gt), Prec::Compare),
185 TKind::DotDot => (Ps::Op(Op::RangeEx), Prec::Range),
186 TKind::DotDotEq => (Ps::Op(Op::RangeIn), Prec::Range),
187 TKind::Amp => (Ps::Op(Op::And), Prec::Binary),
188 TKind::Xor => (Ps::Op(Op::Xor), Prec::Binary),
189 TKind::Bar => (Ps::Op(Op::Or), Prec::Binary),
190 TKind::LtLt => (Ps::Op(Op::Shl), Prec::Shift),
191 TKind::GtGt => (Ps::Op(Op::Shr), Prec::Shift),
192 TKind::Plus => (Ps::Op(Op::Add), Prec::Factor),
193 TKind::Minus => (Ps::Op(Op::Sub), Prec::Factor),
194 TKind::Star => (Ps::Op(Op::Mul), Prec::Term),
195 TKind::Slash => (Ps::Op(Op::Div), Prec::Term),
196 TKind::Rem => (Ps::Op(Op::Rem), Prec::Term),
197
198 TKind::Question => (Ps::Op(Op::Try), Prec::Unary),
199 TKind::Dot => (Ps::Op(Op::Dot), Prec::Project),
200 TKind::LBrack => (Ps::Op(Op::Index), Prec::Project),
201 TKind::LParen => (Ps::Op(Op::Call), Prec::Extend),
202
203 TKind::RParen | TKind::RBrack | TKind::RCurly => (Ps::End, Prec::Max),
204 TKind::As => (Ps::Op(Op::As), Prec::Unary),
205 _ => (Ps::ImplicitDo, Prec::Do),
206 })
207}
208
209impl<'t> Parse<'t> for Expr {
210 type Prec = usize;
211
212 fn parse(p: &mut Parser<'t>, level: usize) -> PResult<Self> {
216 const MIN: usize = Prec::MIN;
217
218 let tok @ &Token { kind, span, .. } = p.peek()?;
220 let (op, prec) = from_prefix(tok)?;
221 no_eof(move || {
222 let mut head = match op {
223 Ps::End if level <= prec.next() => Expr::Omitted,
228 Ps::End => Err(ParseError::NotPrefix(kind, span))?,
229
230 Ps::Id => Expr::Id(p.parse(())?),
231 Ps::Mid => Expr::MetId(p.consume().next()?.lexeme.to_string().as_str().into()),
232 Ps::Lit => Expr::Lit(p.parse(())?),
233 Ps::Use => Expr::Use(p.consume().parse(())?),
234 Ps::Def => Expr::Bind(p.parse(())?),
235 Ps::For => parse_for(p, ())?,
236 Ps::Match => Expr::Match(p.parse(())?),
237 Ps::Lambda | Ps::Lambda0 => {
238 p.consume();
239
240 let args = if kind == TKind::Bar {
241 p.opt(PPrec::Tuple, TKind::Bar)?
242 .map(|At(pat, span): At<Pat>| pat.to_tuple(span).at(span))
243 .unwrap_or(At(Pat::Op(PatOp::Tuple, vec![]), span.merge(p.span())))
244 } else {
245 Pat::Op(PatOp::Tuple, vec![]).at(span)
246 };
247
248 let rety = p
249 .opt_if(PPrec::Max, 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
277 Ps::Op(Op::MetaOuter | Op::MetaInner)
279 if p.consume().expect(TKind::LBrack).is_err() =>
280 {
281 return p.parse(level);
282 }
283 Ps::Op(op @ (Op::MetaOuter | Op::MetaInner)) => Expr::Op(
284 op,
285 vec![
286 p.opt(MIN, TKind::RBrack)?
287 .unwrap_or_else(|| Expr::Omitted.at(span)),
288 p.parse(prec.next())?,
289 ],
290 ),
291 Ps::Op(Op::Block) => Expr::Op(
292 Op::Block,
293 p.consume().opt(MIN, kind.flip())?.into_iter().collect(),
294 ),
295 Ps::Op(Op::Array) => parse_array(p)?,
296 Ps::Op(Op::Group) => match p.consume().opt(MIN, kind.flip())? {
297 Some(value) => Expr::Op(Op::Group, vec![value]),
298 None => Expr::Op(Op::Tuple, vec![]),
299 },
300 Ps::Op(Op::Continue) => p.consume().then(Expr::Op(Op::Continue, vec![])),
301 Ps::Op(op @ (Op::If | Op::While)) => {
302 p.consume();
303 let exprs = vec![
304 p.parse(Prec::Logical.value())?,
306 p.parse(prec.next())?,
307 match p.peek() {
308 Ok(Token { kind: TKind::Else, .. }) => {
309 p.consume().parse(prec.next())?
310 }
311 _ => Expr::Omitted.at(span.merge(p.span())),
312 },
313 ];
314 Expr::Op(op, exprs)
315 }
316 Ps::DoubleRef => p.consume().parse(prec.next()).map(|At(expr, span)| {
317 Expr::Op(
318 Op::Refer,
319 vec![At(Expr::Op(Op::Refer, vec![At(expr, span)]), span)],
320 )
321 })?,
322
323 Ps::Op(op) => Expr::Op(op, vec![p.consume().parse(prec.next())?]),
324 _ => unimplemented!("prefix {op:?}"),
325 };
326
327 while let Ok(Some(tok @ &Token { kind, .. })) = p.peek().allow_eof()
329 && let Ok((op, prec)) = from_infix(tok)
330 && level <= prec.prev()
331 && op != Ps::End
332 {
333 let span = span.merge(p.span());
334
335 head = match op {
336 Ps::Make => match &head {
338 Expr::Id(_) | Expr::MetId(_) => Expr::Make(Box::new(Make(
339 head.at(span),
340 p.consume().list(vec![], (), TKind::Comma, TKind::RCurly)?,
341 ))),
342 _ => break,
343 },
344 Ps::ImplicitDo if p.elide_do => head.and_do(span, p.parse(prec.next())?),
346 Ps::ImplicitDo => break,
347 Ps::Op(Op::Do) => head.and_do(
349 span,
350 match p.consume().peek().allow_eof()? {
351 Some(_) => p.parse(prec.next())?,
352 None => At(Expr::Omitted, p.span()),
353 },
354 ),
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 where Self: Sized {
421 Ok(Self(
422 p.consume().parse(Prec::Tuple.value())?,
423 p.expect(TKind::LCurly)?
424 .list(vec![], (), TKind::Semi, TKind::RCurly)?,
425 ))
426 }
427}
428
429impl<'t> Parse<'t> for MatchArm {
430 type Prec = ();
431
432 fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self>
433 where Self: Sized {
434 let pat = p.parse(PPrec::Min)?;
442 p.expect(TKind::FatArrow)?;
443 let body = p.parse(Prec::Body.value())?;
444
445 Ok(Self(pat, body))
446 }
447}
448
449fn parse_for(p: &mut Parser<'_>, _level: ()) -> PResult<Expr> {
451 let pat = p.consume().parse(PPrec::Tuple)?;
453 let iter: At<Expr> = p.expect(TKind::In)?.parse(Prec::Logical.next())?;
455 let pass: At<Expr> = p.parse(Prec::Body.next())?;
457 let pspan = pass.1;
458 let fail = match p.next_if(TKind::Else).allow_eof()? {
460 Some(Ok(_)) => p.parse(Prec::Body.next())?,
461 _ => Expr::Omitted.at(pspan),
462 };
463 Ok(Expr::Bind(Box::new(Bind(
476 BindOp::For,
477 vec![],
478 pat,
479 vec![iter, pass, fail],
480 ))))
481}
482
483#[rustfmt::skip]
486#[allow(clippy::type_complexity)]
487fn from_bind(p: &mut Parser<'_>) -> PResult<(BindOp, PPrec, Option<TKind>, Option<Prec>, Option<Prec>)> {
488 let bk = match p.peek()?.kind {
489 TKind::Let => (BindOp::Let, PPrec::Tuple, Some(TKind::Eq), Some(Prec::Tuple), Some(Prec::Body)),
491 TKind::Type => (BindOp::Type, PPrec::Alt, Some(TKind::Eq), Some(Prec::Tuple), None),
492 TKind::Struct => (BindOp::Struct, PPrec::Tuple, None, None, None),
493 TKind::Enum => (BindOp::Enum, PPrec::Tuple, None, None, None),
494 TKind::Fn => (BindOp::Fn, PPrec::Fn, None, Some(Prec::Body), None),
495 TKind::Mod => (BindOp::Mod, PPrec::Max, None, Some(Prec::Body), None),
496 TKind::Impl => (BindOp::Impl, PPrec::Fn, None, Some(Prec::Body), None),
497 other => return Err(ParseError::NotBind(other, p.span()))
498 };
499
500 p.consume();
501 Ok(bk)
502}
503
504impl<'t> Parse<'t> for Bind {
505 type Prec = ();
506
507 fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> {
508 let (level, patp, arrow, bodyp, failp) = from_bind(p)?;
510
511 let generics = match p.next_if(TKind::Lt)? {
513 Ok(_) => p.list(vec![], (), TKind::Comma, TKind::Gt)?,
514 Err(_) => vec![],
515 };
516
517 let pat = p.parse(patp)?;
519
520 let Some(bodyp) = bodyp else {
521 return Ok(Self(level, generics, pat, vec![]));
522 };
523
524 if let Some(arrow) = arrow {
526 if p.next_if(arrow).allow_eof()?.is_none_or(|v| v.is_err()) {
527 return Ok(Self(level, generics, pat, vec![]));
528 }
529 } else {
530 p.next_if(TKind::Eq).allow_eof()?;
532 }
533
534 let body = p.parse(bodyp.value())?;
536
537 let Some(failp) = failp else {
538 return Ok(Self(level, generics, pat, vec![body]));
539 };
540
541 if p.next_if(TKind::Else)
543 .allow_eof()?
544 .is_none_or(|v| v.is_err())
545 {
546 return Ok(Self(level, generics, pat, vec![body]));
547 }
548
549 let fail = p.parse(failp.value())?;
550
551 Ok(Self(level, generics, pat, vec![body, fail]))
552 }
553}
554
555impl<'t> Parse<'t> for MakeArm {
556 type Prec = ();
557
558 fn parse(p: &mut Parser<'t>, _level: ()) -> PResult<Self> {
559 let name = p
560 .next_if(TKind::Identifier)?
561 .map_err(|tk| ParseError::Expected(TKind::Identifier, tk, p.span()))?;
562 Ok(MakeArm(
563 name.lexeme
564 .str()
565 .expect("Identifier should have String")
566 .into(),
567 p.opt_if(Prec::Tuple.next(), TKind::Colon)?,
568 ))
569 }
570}