1use std::{
4 collections::{BTreeMap, HashSet, VecDeque},
5 sync::Arc,
6 vec,
7};
8
9use rexlang_ast::expr::{
10 ClassDecl, ClassMethodSig, Decl, DeclareFnDecl, Expr, FnDecl, ImportClause, ImportDecl,
11 ImportItem, ImportPath, InstanceDecl, InstanceMethodImpl, NameRef, Pattern, Program, Scope,
12 Symbol, TypeConstraint, TypeDecl, TypeExpr, TypeVariant, Var, intern,
13};
14use rexlang_lexer::{
15 Token, Tokens,
16 span::{Position, Span, Spanned},
17};
18
19use crate::{error::ParserErr, op::Operator};
20use rexlang_util::GasMeter;
21
22pub struct Parser {
23 token_cursor: usize,
24 tokens: Vec<Token>,
25 eof: Span,
26 errors: Vec<ParserErr>,
27 limits: ParserLimits,
28 nesting_depth: usize,
29}
30
31#[derive(Clone, Copy, Debug)]
32pub struct ParserLimits {
33 pub max_nesting: Option<usize>,
34}
35
36impl ParserLimits {
37 pub fn unlimited() -> Self {
38 Self { max_nesting: None }
39 }
40
41 pub fn safe_defaults() -> Self {
42 Self {
43 max_nesting: Some(512),
44 }
45 }
46}
47
48impl Default for ParserLimits {
49 fn default() -> Self {
50 Self::unlimited()
51 }
52}
53
54impl Parser {
55 fn operator_token_name(token: &Token) -> Option<(&'static str, Span)> {
56 match token {
57 Token::Add(span, ..) => Some(("+", *span)),
58 Token::And(span, ..) => Some(("&&", *span)),
59 Token::Concat(span, ..) => Some(("++", *span)),
60 Token::Div(span, ..) => Some(("/", *span)),
61 Token::Eq(span, ..) => Some(("==", *span)),
62 Token::Ne(span, ..) => Some(("!=", *span)),
63 Token::Ge(span, ..) => Some((">=", *span)),
64 Token::Gt(span, ..) => Some((">", *span)),
65 Token::Le(span, ..) => Some(("<=", *span)),
66 Token::Lt(span, ..) => Some(("<", *span)),
67 Token::Mod(span, ..) => Some(("%", *span)),
68 Token::Mul(span, ..) => Some(("*", *span)),
69 Token::Or(span, ..) => Some(("||", *span)),
70 Token::Sub(span, ..) => Some(("-", *span)),
71 _ => None,
72 }
73 }
74
75 fn parse_value_name(&mut self) -> Result<(Symbol, Span), ParserErr> {
76 match self.current_token() {
77 Token::Ident(name, span, ..) => {
78 self.next_token();
79 Ok((intern(&name), span))
80 }
81 token => {
82 if let Some((name, span)) = Self::operator_token_name(&token) {
83 self.next_token();
84 Ok((intern(name), span))
85 } else {
86 Err(ParserErr::new(
87 *token.span(),
88 format!("expected identifier or operator name got {}", token),
89 ))
90 }
91 }
92 }
93 }
94
95 pub fn new(tokens: Tokens) -> Parser {
96 let mut parser = Parser {
97 token_cursor: 0,
98 tokens: tokens
99 .items
100 .into_iter()
101 .filter_map(|token| match token {
102 Token::Whitespace(..) => None,
103 token => Some(token),
104 })
105 .collect(),
106 eof: tokens.eof,
107 errors: Vec::new(),
108 limits: ParserLimits::default(),
109 nesting_depth: 0,
110 };
111 parser.strip_comments();
113 parser
114 }
115
116 pub fn set_limits(&mut self, limits: ParserLimits) {
117 self.limits = limits;
118 }
119
120 fn with_nesting<T>(
121 &mut self,
122 span: Span,
123 f: impl FnOnce(&mut Self) -> Result<T, ParserErr>,
124 ) -> Result<T, ParserErr> {
125 if let Some(max) = self.limits.max_nesting
126 && self.nesting_depth >= max
127 {
128 return Err(ParserErr::new(
129 span,
130 format!("maximum nesting depth exceeded (max {max})"),
131 ));
132 }
133 self.nesting_depth += 1;
134 let res = f(self);
135 self.nesting_depth = self.nesting_depth.saturating_sub(1);
136 res
137 }
138
139 fn skip_newlines(&mut self) {
140 while self.token_cursor < self.tokens.len() {
141 if matches!(self.tokens[self.token_cursor], Token::WhitespaceNewline(..)) {
142 self.token_cursor += 1;
143 continue;
144 }
145 break;
146 }
147 }
148
149 fn current_token(&mut self) -> Token {
150 self.skip_newlines();
151 if self.token_cursor < self.tokens.len() {
152 return self.tokens[self.token_cursor].clone();
153 }
154 Token::Eof(self.eof)
155 }
156
157 fn peek_token(&mut self, n: usize) -> Token {
158 self.skip_newlines();
159 let mut cursor = self.token_cursor;
160 let mut seen = 0usize;
161 while cursor < self.tokens.len() {
162 if matches!(self.tokens[cursor], Token::WhitespaceNewline(..)) {
163 cursor += 1;
164 continue;
165 }
166 if seen == n {
167 return self.tokens[cursor].clone();
168 }
169 seen += 1;
170 cursor += 1;
171 }
172 Token::Eof(self.eof)
173 }
174
175 fn next_token(&mut self) {
176 self.token_cursor += 1;
177 self.skip_newlines();
178 }
179
180 fn expect_colon(&mut self) -> Result<(), ParserErr> {
181 let token = self.current_token();
182 match token {
183 Token::Colon(..) => {
184 self.next_token();
185 Ok(())
186 }
187 token => Err(ParserErr::new(
188 *token.span(),
189 format!("expected `:` got {}", token),
190 )),
191 }
192 }
193
194 fn expect_assign(&mut self) -> Result<(), ParserErr> {
195 let token = self.current_token();
196 match token {
197 Token::Assign(..) => {
198 self.next_token();
199 Ok(())
200 }
201 token => Err(ParserErr::new(
202 *token.span(),
203 format!("expected `=` got {}", token),
204 )),
205 }
206 }
207
208 fn expect_paren_r(&mut self) -> Result<Span, ParserErr> {
209 let token = self.current_token();
210 match token {
211 Token::ParenR(span, ..) => {
212 self.next_token();
213 Ok(span)
214 }
215 token => Err(ParserErr::new(
216 *token.span(),
217 format!("expected `)` got {}", token),
218 )),
219 }
220 }
221
222 fn expect_ident(&mut self, what: &str) -> Result<(String, Span), ParserErr> {
223 match self.current_token() {
224 Token::Ident(name, span, ..) => {
225 self.next_token();
226 Ok((name, span))
227 }
228 token => Err(ParserErr::new(
229 *token.span(),
230 format!("expected {what} got {}", token),
231 )),
232 }
233 }
234
235 fn is_value_name_token(token: &Token) -> bool {
236 matches!(token, Token::Ident(..)) || Self::operator_token_name(token).is_some()
237 }
238
239 fn parse_layout_block<T>(
240 &mut self,
241 has_block: bool,
242 block_indent: Option<usize>,
243 mut parse_item: impl FnMut(&mut Self) -> Result<T, ParserErr>,
244 ) -> Result<Vec<T>, ParserErr> {
245 if !has_block {
246 return Ok(Vec::new());
247 }
248
249 let mut items = Vec::new();
250 loop {
251 let token = self.current_token();
252 if !Self::is_value_name_token(&token) {
253 break;
254 }
255 let span = *token.span();
256 if let Some(indent) = block_indent
257 && span.begin.column != indent
258 {
259 break;
260 }
261 items.push(parse_item(self)?);
262 }
263 Ok(items)
264 }
265
266 fn find_token_at_depth0(
267 &self,
268 start: usize,
269 end: usize,
270 mut matches: impl FnMut(&Token) -> bool,
271 ) -> Option<usize> {
272 let mut depth = 0usize;
273 let end = end.min(self.tokens.len());
274 for i in start..end {
275 match &self.tokens[i] {
276 Token::ParenL(..) | Token::BracketL(..) | Token::BraceL(..) => depth += 1,
277 Token::ParenR(..) | Token::BracketR(..) | Token::BraceR(..) => {
278 depth = depth.saturating_sub(1)
279 }
280 _ => {}
281 }
282 if depth == 0 && matches(&self.tokens[i]) {
283 return Some(i);
284 }
285 }
286 None
287 }
288
289 fn find_same_line_end(&self, start_idx: usize) -> Result<usize, ParserErr> {
290 let start_line = self
291 .tokens
292 .get(start_idx)
293 .ok_or_else(|| ParserErr::new(self.eof, "unexpected EOF".to_string()))?
294 .span()
295 .begin
296 .line;
297
298 let mut depth = 0usize;
299 let mut end_idx = start_idx;
300 for i in start_idx..self.tokens.len() {
301 let tok = &self.tokens[i];
302 if depth == 0 && tok.span().begin.line > start_line {
303 break;
304 }
305 match tok {
306 Token::ParenL(..) | Token::BracketL(..) | Token::BraceL(..) => depth += 1,
307 Token::ParenR(..) | Token::BracketR(..) | Token::BraceR(..) => {
308 depth = depth.saturating_sub(1)
309 }
310 _ => {}
311 }
312 end_idx = i + 1;
313 }
314 Ok(end_idx)
315 }
316
317 fn find_dedent_end(&self, start_idx: usize, base_indent: usize) -> Result<usize, ParserErr> {
318 let mut depth = 0usize;
319 let mut end_idx = start_idx;
320 for i in start_idx..self.tokens.len() {
321 let tok = &self.tokens[i];
322 match tok {
323 Token::ParenL(..) | Token::BracketL(..) | Token::BraceL(..) => depth += 1,
324 Token::ParenR(..) | Token::BracketR(..) | Token::BraceR(..) => {
325 depth = depth.saturating_sub(1)
326 }
327 Token::WhitespaceNewline(..) if depth == 0 => {
328 let mut j = i + 1;
329 while j < self.tokens.len()
330 && matches!(self.tokens[j], Token::WhitespaceNewline(..))
331 {
332 j += 1;
333 }
334 if j >= self.tokens.len() {
335 return Ok(i);
336 }
337 if self.tokens[j].span().begin.column <= base_indent {
338 return Ok(i);
339 }
340 }
341 _ => {}
342 }
343 end_idx = i + 1;
344 }
345 Ok(end_idx)
346 }
347
348 fn paren_group_has_top_level_comma(&self, paren_start: usize) -> bool {
349 let mut depth = 0usize;
350 for i in (paren_start + 1)..self.tokens.len() {
351 match self.tokens[i] {
352 Token::ParenL(..) | Token::BracketL(..) | Token::BraceL(..) => depth += 1,
353 Token::ParenR(..) | Token::BracketR(..) | Token::BraceR(..) => {
354 if depth == 0 {
355 break;
356 }
357 depth = depth.saturating_sub(1)
358 }
359 Token::Comma(..) if depth == 0 => return true,
360 _ => {}
361 }
362 }
363 false
364 }
365
366 fn paren_group_has_top_level_colon(&self, paren_start: usize) -> bool {
367 let mut depth = 0usize;
368 for i in (paren_start + 1)..self.tokens.len() {
369 match self.tokens[i] {
370 Token::ParenL(..) | Token::BracketL(..) | Token::BraceL(..) => depth += 1,
371 Token::ParenR(..) | Token::BracketR(..) | Token::BraceR(..) => {
372 if depth == 0 {
373 break;
374 }
375 depth = depth.saturating_sub(1)
376 }
377 Token::Colon(..) if depth == 0 => return true,
378 _ => {}
379 }
380 }
381 false
382 }
383
384 fn parse_legacy_param_group(&mut self) -> Result<Vec<(Var, TypeExpr)>, ParserErr> {
385 match self.current_token() {
386 Token::ParenL(..) => self.next_token(),
387 token => {
388 return Err(ParserErr::new(
389 *token.span(),
390 format!("expected `(` got {}", token),
391 ));
392 }
393 }
394
395 let mut params = Vec::new();
396 if matches!(self.current_token(), Token::ParenR(..)) {
397 self.next_token();
398 return Ok(params);
399 }
400
401 loop {
402 let (param_name, param_span) = self.expect_ident("parameter name")?;
403 self.expect_colon()?;
404
405 let ty_start = self.token_cursor;
406 let ty_end = self
407 .find_token_at_depth0(ty_start, self.tokens.len(), |t| {
408 matches!(t, Token::Comma(..) | Token::ParenR(..))
409 })
410 .ok_or_else(|| {
411 ParserErr::new(
412 self.eof,
413 "expected `,` or `)` after parameter type".to_string(),
414 )
415 })?;
416 let ann = self.parse_type_expr_slice(&self.tokens[ty_start..ty_end])?;
417 self.token_cursor = ty_end;
418 params.push((Var::with_span(param_span, param_name), ann));
419
420 match self.current_token() {
421 Token::Comma(..) => {
422 self.next_token();
423 continue;
424 }
425 Token::ParenR(..) => {
426 self.next_token();
427 break;
428 }
429 token => {
430 return Err(ParserErr::new(
431 *token.span(),
432 format!("expected `,` or `)` got {}", token),
433 ));
434 }
435 }
436 }
437
438 Ok(params)
439 }
440
441 fn next_token_raw(&mut self) {
448 self.token_cursor += 1;
449 }
450
451 fn strip_comments(&mut self) {
452 let mut cursor = 0;
453
454 while cursor < self.tokens.len() {
455 match self.tokens[cursor] {
456 Token::CommentL(..) => {
457 self.tokens.remove(cursor);
458 while cursor < self.tokens.len() {
459 if let Token::CommentR(..) = self.tokens[cursor] {
460 self.tokens.remove(cursor);
461 break;
462 }
463 self.tokens.remove(cursor);
464 }
465 }
466 _ => {
467 cursor += 1;
468 continue;
469 }
470 }
471 }
472 }
473
474 fn record_error(&mut self, e: ParserErr) {
475 self.errors.push(e);
476 }
477
478 fn parse_program_core(&mut self) -> Result<Program, Vec<ParserErr>> {
479 let mut decls = Vec::new();
480 loop {
481 let mut is_pub = false;
482 if let Token::Pub(..) = self.current_token() {
483 is_pub = true;
484 self.next_token();
485 }
486
487 match self.current_token() {
488 Token::Type(..) => match self.parse_type_decl(is_pub) {
489 Ok(decl) => decls.push(Decl::Type(decl)),
490 Err(e) => {
491 self.record_error(e);
492 break;
493 }
494 },
495 Token::Fn(..) => match self.parse_fn_decl(is_pub) {
496 Ok(decl) => decls.push(Decl::Fn(decl)),
497 Err(e) => {
498 self.record_error(e);
499 break;
500 }
501 },
502 Token::Declare(..) => match self.parse_declare_fn_decl_toplevel(is_pub) {
503 Ok(decl) => decls.push(Decl::DeclareFn(decl)),
504 Err(e) => {
505 self.record_error(e);
506 break;
507 }
508 },
509 Token::Import(..) => match self.parse_import_decl(is_pub) {
510 Ok(decl) => decls.push(Decl::Import(decl)),
511 Err(e) => {
512 self.record_error(e);
513 break;
514 }
515 },
516 Token::Class(..) => match self.parse_class_decl(is_pub) {
517 Ok(decl) => decls.push(Decl::Class(decl)),
518 Err(e) => {
519 self.record_error(e);
520 break;
521 }
522 },
523 Token::Instance(..) => match self.parse_instance_decl(is_pub) {
524 Ok(decl) => decls.push(Decl::Instance(decl)),
525 Err(e) => {
526 self.record_error(e);
527 break;
528 }
529 },
530 _ => break,
531 }
532 }
533
534 let expr = if matches!(self.current_token(), Token::Eof(..)) {
535 Expr::Tuple(self.eof, vec![])
538 } else {
539 match self.parse_expr() {
540 Ok(expr) => expr,
541 Err(e) => {
542 self.record_error(e);
543 return Err(self.errors.clone());
544 }
545 }
546 };
547
548 match self.current_token() {
551 Token::Eof(..) => {}
552 token => self.record_error(ParserErr::new(
553 *token.span(),
554 format!("unexpected {}", token),
555 )),
556 }
557
558 if !self.errors.is_empty() {
559 Err(self.errors.clone())
560 } else {
561 Ok(Program {
562 decls,
563 expr: Arc::new(expr),
564 })
565 }
566 }
567
568 pub fn parse_program(&mut self, gas: &mut GasMeter) -> Result<Program, Vec<ParserErr>> {
569 let token_cost = gas
570 .costs
571 .parse_token
572 .saturating_mul(self.tokens.len() as u64);
573 if let Err(e) = gas.charge(token_cost) {
574 return Err(vec![ParserErr::new(Span::default(), e.to_string())]);
575 }
576
577 let program = self.parse_program_core()?;
578 let expr_nodes = count_expr_nodes(program.expr.as_ref());
579 let decl_nodes = program.decls.len() as u64;
580 let node_cost = gas
581 .costs
582 .parse_node
583 .saturating_mul(expr_nodes.saturating_add(decl_nodes));
584 if let Err(e) = gas.charge(node_cost) {
585 return Err(vec![ParserErr::new(Span::default(), e.to_string())]);
586 }
587 Ok(program)
588 }
589
590 fn parse_expr(&mut self) -> Result<Expr, ParserErr> {
591 let span = *self.current_token().span();
592 self.with_nesting(span, |this| {
593 let lhs_expr = this.parse_unary_expr()?;
594 this.parse_binary_expr(lhs_expr)
595 })
596 }
597
598 fn parse_binary_expr(&mut self, lhs_expr: Expr) -> Result<Expr, ParserErr> {
599 let span = *lhs_expr.span();
600 self.with_nesting(span, move |this| {
601 let lhs_expr_span = lhs_expr.span();
602
603 let token = match this.current_token() {
605 Token::Eof(..) => return Ok(lhs_expr),
608 token => token,
609 };
610 let prec = token.precedence();
611
612 let operator = match token {
614 Token::Add(..) => Operator::Add,
615 Token::And(..) => Operator::And,
616 Token::Concat(..) => Operator::Concat,
617 Token::ColonColon(..) => {
618 let operator_span = token.span();
619 this.next_token();
620
621 let rhs_expr = this.parse_unary_expr()?;
622 let rhs_expr_span = *rhs_expr.span();
623
624 let next_binary_expr_takes_precedence = match this.current_token() {
625 Token::Eof(..) => false,
626 token if prec > token.precedence() => false,
627 token if prec == token.precedence() => !matches!(
628 token,
629 Token::Add(..)
630 | Token::And(..)
631 | Token::Concat(..)
632 | Token::Div(..)
633 | Token::Mul(..)
634 | Token::Mod(..)
635 | Token::Or(..)
636 | Token::Sub(..)
637 ),
638 _ => true,
639 };
640
641 let rhs_expr = if next_binary_expr_takes_precedence {
642 this.parse_binary_expr(rhs_expr)?
643 } else {
644 rhs_expr
645 };
646
647 let cons_span = Span::from_begin_end(lhs_expr_span.begin, operator_span.end);
648 let outer_span = Span::from_begin_end(lhs_expr_span.begin, rhs_expr_span.end);
649 return this.parse_binary_expr(Expr::App(
650 outer_span,
651 Arc::new(Expr::App(
652 cons_span,
653 Arc::new(Expr::Var(Var::with_span(*operator_span, "Cons"))),
654 Arc::new(lhs_expr),
655 )),
656 Arc::new(rhs_expr),
657 ));
658 }
659 Token::Div(..) => Operator::Div,
660 Token::Eq(..) => Operator::Eq,
661 Token::Ne(..) => Operator::Ne,
662 Token::Ge(..) => Operator::Ge,
663 Token::Gt(..) => Operator::Gt,
664 Token::Le(..) => Operator::Le,
665 Token::Lt(..) => Operator::Lt,
666 Token::Mod(..) => Operator::Mod,
667 Token::Mul(..) => Operator::Mul,
668 Token::Or(..) => Operator::Or,
669 Token::Sub(..) => Operator::Sub,
670 _ => {
671 return Ok(lhs_expr);
672 }
673 };
674 let operator_span = token.span();
675
676 this.next_token();
678
679 let rhs_expr = this.parse_unary_expr()?;
681 let rhs_expr_span = *rhs_expr.span();
682
683 let next_binary_expr_takes_precedence = match this.current_token() {
684 Token::Eof(..) => false,
686 token if prec > token.precedence() => false,
688 token if prec == token.precedence() => {
690 !matches!(
692 token,
693 Token::Add(..)
694 | Token::And(..)
695 | Token::Concat(..)
696 | Token::Div(..)
697 | Token::Mul(..)
698 | Token::Mod(..)
699 | Token::Or(..)
700 | Token::Sub(..)
701 )
702 }
703 _ => true,
705 };
706
707 let rhs_expr = if next_binary_expr_takes_precedence {
708 this.parse_binary_expr(rhs_expr)?
709 } else {
710 rhs_expr
711 };
712
713 let inner_span = Span::from_begin_end(lhs_expr_span.begin, operator_span.end);
714 let outer_span = Span::from_begin_end(lhs_expr_span.begin, rhs_expr_span.end);
715
716 this.parse_binary_expr(Expr::App(
717 outer_span,
718 Arc::new(Expr::App(
719 inner_span,
720 Arc::new(Expr::Var(Var::with_span(
721 *operator_span,
722 operator.to_string(),
723 ))),
724 Arc::new(lhs_expr),
725 )),
726 Arc::new(rhs_expr),
727 ))
728 })
729 }
730
731 fn parse_unary_expr(&mut self) -> Result<Expr, ParserErr> {
732 let mut call_base_expr = self.parse_postfix_expr()?;
734 let call_base_expr_span = *call_base_expr.span();
735
736 let mut call_arg_exprs = VecDeque::new();
737 loop {
738 let call_arg_expr = match self.current_token() {
739 Token::ParenL(..)
740 | Token::BracketL(..)
741 | Token::BraceL(..)
742 | Token::Bool(..)
743 | Token::Float(..)
744 | Token::Int(..)
745 | Token::String(..)
746 | Token::Question(..)
747 | Token::Ident(..)
748 | Token::BackSlash(..)
749 | Token::Let(..)
750 | Token::If(..)
751 | Token::Match(..) => self.parse_postfix_expr(),
752 _ => break,
753 }?;
754 call_arg_exprs.push_back(call_arg_expr);
755 }
756
757 while let Some(call_arg_expr) = call_arg_exprs.pop_front() {
758 let call_arg_expr_span_end = call_arg_expr.span().end;
759 call_base_expr = Expr::App(
760 Span::from_begin_end(call_base_expr_span.begin, call_arg_expr_span_end),
761 Arc::new(call_base_expr),
762 Arc::new(call_arg_expr),
763 );
764 }
765 while let Token::Is(..) = self.current_token() {
766 self.next_token();
767 let ann = self.parse_type_expr()?;
768 let span = Span::from_begin_end(call_base_expr.span().begin, ann.span().end);
769 call_base_expr = Expr::Ann(span, Arc::new(call_base_expr), ann);
770 }
771 Ok(call_base_expr)
772 }
773
774 fn parse_postfix_expr(&mut self) -> Result<Expr, ParserErr> {
775 let mut base = self.parse_atom_expr()?;
776 while let Token::Dot(..) = self.current_token() {
777 self.next_token();
778
779 let (field, end) = match self.current_token() {
780 Token::Ident(name, span, ..) => {
781 let name = intern(&name);
782 let end = span.end;
783 self.next_token();
784 (name, end)
785 }
786 Token::Int(value, span) => {
787 let name = intern(&value.to_string());
788 let end = span.end;
789 self.next_token();
790 (name, end)
791 }
792 token => {
793 return Err(ParserErr::new(
794 *token.span(),
795 "expected field name after `.`",
796 ));
797 }
798 };
799
800 let span = Span::from_begin_end(base.span().begin, end);
801 base = Expr::Project(span, Arc::new(base), field);
802 }
803 Ok(base)
804 }
805
806 fn parse_atom_expr(&mut self) -> Result<Expr, ParserErr> {
807 match self.current_token() {
808 Token::ParenL(..) => self.parse_paren_expr(),
809 Token::BracketL(..) => self.parse_bracket_expr(),
810 Token::BraceL(..) => self.parse_brace_expr(),
811 Token::Bool(..) => self.parse_literal_bool_expr(),
812 Token::Float(..) => self.parse_literal_float_expr(),
813 Token::Int(..) => self.parse_literal_int_expr(),
814 Token::String(..) => self.parse_literal_str_expr(),
815 Token::Question(..) => self.parse_hole_expr(),
816 Token::Ident(..) => self.parse_ident_expr(),
817 Token::BackSlash(..) => self.parse_lambda_expr(),
818 Token::Let(..) => self.parse_let_expr(),
819 Token::If(..) => self.parse_if_expr(),
820 Token::Match(..) => self.parse_match_expr(),
821 Token::Sub(..) => self.parse_neg_expr(),
822 Token::Eof(span) => Err(ParserErr::new(span, "unexpected EOF".to_string())),
823 token => Err(ParserErr::new(
824 *token.span(),
825 format!("unexpected {}", token),
826 )),
827 }
828 }
829
830 fn parse_paren_expr(&mut self) -> Result<Expr, ParserErr> {
831 let span_begin = match self.current_token() {
833 Token::ParenL(span, ..) => {
834 self.next_token();
835 span
836 }
837 token => {
838 return Err(ParserErr::new(
839 *token.span(),
840 format!("expected `(` got {}", token),
841 ));
842 }
843 };
844
845 self.with_nesting(span_begin, |this| {
846 let expr = match this.current_token() {
848 Token::ParenR(span, ..) => {
849 this.next_token();
850 return Ok(Expr::Tuple(
852 Span::from_begin_end(span_begin.begin, span.end),
853 vec![],
854 ));
855 }
856 Token::Add(span, ..) => {
857 this.next_token();
858 Expr::Var(Var::with_span(span, "+"))
859 }
860 Token::And(span, ..) => {
861 this.next_token();
862 Expr::Var(Var::with_span(span, "&&"))
863 }
864 Token::Concat(span, ..) => {
865 this.next_token();
866 Expr::Var(Var::with_span(span, "++"))
867 }
868 Token::Div(span, ..) => {
869 this.next_token();
870 Expr::Var(Var::with_span(span, "/"))
871 }
872 Token::Eq(span, ..) => {
873 this.next_token();
874 Expr::Var(Var::with_span(span, "=="))
875 }
876 Token::Ge(span, ..) => {
877 this.next_token();
878 Expr::Var(Var::with_span(span, ">="))
879 }
880 Token::Gt(span, ..) => {
881 this.next_token();
882 Expr::Var(Var::with_span(span, ">"))
883 }
884 Token::Le(span, ..) => {
885 this.next_token();
886 Expr::Var(Var::with_span(span, "<="))
887 }
888 Token::Lt(span, ..) => {
889 this.next_token();
890 Expr::Var(Var::with_span(span, "<"))
891 }
892 Token::Mod(span, ..) => {
893 this.next_token();
894 Expr::Var(Var::with_span(span, "%"))
895 }
896 Token::Mul(span, ..) => {
897 this.next_token();
898 Expr::Var(Var::with_span(span, "*"))
899 }
900 Token::Or(span, ..) => {
901 this.next_token();
902 Expr::Var(Var::with_span(span, "||"))
903 }
904 Token::Sub(span, ..) => {
905 if let Token::ParenR(..) = this.peek_token(1) {
906 this.next_token();
917 Expr::Var(Var::with_span(span, "-"))
918 } else {
919 this.parse_expr()?
920 }
921 }
922 _ => this.parse_expr()?,
923 };
924
925 let span_end = match this.current_token() {
927 Token::ParenR(span, ..) => {
928 this.next_token();
929 span
930 }
931 Token::Comma(..) => {
932 return this.parse_tuple(span_begin, expr);
934 }
935 token => {
936 this.record_error(ParserErr::new(*token.span(), "expected `)`"));
937 return Ok(expr);
938 }
939 };
940
941 let expr = expr.with_span_begin_end(span_begin.begin, span_end.end);
942 Ok(expr)
943 })
944 }
945
946 fn parse_tuple(&mut self, span_begin: Span, first_item: Expr) -> Result<Expr, ParserErr> {
947 let mut items = vec![Arc::new(first_item)];
948 loop {
949 match self.current_token() {
951 Token::Comma(..) => self.next_token(),
952 Token::ParenR(end_span) => {
953 self.next_token();
954 return Ok(Expr::Tuple(
955 Span::from_begin_end(span_begin.begin, end_span.end),
956 items,
957 ));
958 }
959 _ => items.push(Arc::new(self.parse_expr()?)),
960 }
961 }
962 }
963
964 fn parse_bracket_expr(&mut self) -> Result<Expr, ParserErr> {
965 let span_begin = match self.current_token() {
967 Token::BracketL(span, ..) => {
968 self.next_token();
969 span
970 }
971 token => {
972 return Err(ParserErr::new(
973 *token.span(),
974 format!("expected `[` got {}", token),
975 ));
976 }
977 };
978
979 self.with_nesting(span_begin, |this| {
980 let mut exprs = Vec::new();
981 loop {
982 if let Token::BracketR(..) = this.current_token() {
983 break;
984 }
985
986 exprs.push(Arc::new(this.parse_expr()?));
988 match this.current_token() {
990 Token::Comma(..) => this.next_token(),
991 Token::Eof(span) => {
992 this.record_error(ParserErr::new(span, "expected `,` or `]`"));
993 break;
994 }
995 _ => {
996 break;
997 }
998 };
999 }
1000
1001 let span_end = match this.current_token() {
1003 Token::BracketR(span, ..) => {
1004 this.next_token();
1005 span.end
1006 }
1007 token => {
1008 this.record_error(ParserErr::new(
1009 *token.span(),
1010 format!("expected `]` got {}", token),
1011 ));
1012
1013 return Ok(Expr::List(
1014 Span::from_begin_end(span_begin.begin, token.span().end),
1015 exprs,
1016 ));
1017 }
1018 };
1019
1020 Ok(Expr::List(
1021 Span::from_begin_end(span_begin.begin, span_end),
1022 exprs,
1023 ))
1024 })
1025 }
1026
1027 fn parse_brace_expr(&mut self) -> Result<Expr, ParserErr> {
1028 let span_begin = match self.current_token() {
1030 Token::BraceL(span, ..) => {
1031 self.next_token();
1032 span
1033 }
1034 token => {
1035 return Err(ParserErr::new(
1036 *token.span(),
1037 format!("expected `{{` got {}", token),
1038 ));
1039 }
1040 };
1041
1042 self.with_nesting(span_begin, |this| {
1043 let span_begin_pos = span_begin.begin;
1044
1045 if let Token::BraceR(span, ..) = this.current_token() {
1047 this.next_token();
1048 return Ok(Expr::Dict(
1049 Span::from_begin_end(span_begin_pos, span.end),
1050 BTreeMap::new(),
1051 ));
1052 }
1053
1054 let looks_like_dict_literal = matches!(this.current_token(), Token::Ident(..))
1058 && matches!(this.peek_token(1), Token::Assign(..));
1059
1060 if looks_like_dict_literal {
1061 return this.parse_dict_expr_after_lbrace(span_begin_pos);
1062 }
1063
1064 let base = match this.parse_expr() {
1065 Ok(expr) => expr,
1066 Err(err) => {
1067 this.record_error(err);
1068 while !matches!(this.current_token(), Token::BraceR(..) | Token::Eof(..)) {
1069 this.next_token();
1070 }
1071 if let Token::BraceR(..) = this.current_token() {
1072 this.next_token();
1073 }
1074 return Ok(Expr::Dict(
1075 Span::from_begin_end(span_begin_pos, Position::new(0, 0)),
1076 BTreeMap::new(),
1077 ));
1078 }
1079 };
1080
1081 match this.current_token() {
1082 Token::With(..) => this.next_token(),
1083 token => {
1084 this.record_error(ParserErr::new(*token.span(), "expected `with`"));
1085 while !matches!(this.current_token(), Token::BraceR(..) | Token::Eof(..)) {
1086 this.next_token();
1087 }
1088 if let Token::BraceR(..) = this.current_token() {
1089 this.next_token();
1090 }
1091 return Ok(base);
1092 }
1093 };
1094
1095 let updates = match this.parse_dict_expr() {
1096 Ok(Expr::Dict(_, kvs)) => kvs,
1097 Ok(other) => {
1098 this.record_error(ParserErr::new(*other.span(), "expected `{...}`"));
1099 BTreeMap::new()
1100 }
1101 Err(err) => {
1102 this.record_error(err);
1103 BTreeMap::new()
1104 }
1105 };
1106
1107 let span_end = match this.current_token() {
1109 Token::BraceR(span, ..) => {
1110 this.next_token();
1111 span.end
1112 }
1113 token => {
1114 this.record_error(ParserErr::new(
1115 *token.span(),
1116 format!("expected `}}` got {}", token),
1117 ));
1118 Position::new(0, 0)
1119 }
1120 };
1121
1122 Ok(Expr::RecordUpdate(
1123 Span::from_begin_end(span_begin_pos, span_end),
1124 Arc::new(base),
1125 updates,
1126 ))
1127 })
1128 }
1129
1130 fn parse_dict_expr(&mut self) -> Result<Expr, ParserErr> {
1131 let span_begin = match self.current_token() {
1133 Token::BraceL(span, ..) => {
1134 self.next_token();
1135 span.begin
1136 }
1137 token => {
1138 return Err(ParserErr::new(
1139 *token.span(),
1140 format!("expected `{{` got {}", token),
1141 ));
1142 }
1143 };
1144
1145 self.with_nesting(Span::from_begin_end(span_begin, span_begin), |this| {
1146 this.parse_dict_expr_after_lbrace(span_begin)
1147 })
1148 }
1149
1150 fn parse_dict_expr_after_lbrace(&mut self, span_begin: Position) -> Result<Expr, ParserErr> {
1151 let mut kvs = Vec::new();
1152 loop {
1153 if let Token::BraceR(..) = self.current_token() {
1154 break;
1155 }
1156
1157 let var = match self.parse_ident_expr()? {
1159 Expr::Var(var) => var,
1160 _ => unreachable!(),
1161 };
1162 match self.current_token() {
1164 Token::Assign(..) => self.next_token(),
1165 token => {
1166 self.record_error(ParserErr::new(*token.span(), "expected `=`"));
1167 break;
1168 }
1169 };
1170 kvs.push((var.name, Arc::new(self.parse_expr()?)));
1172 match self.current_token() {
1174 Token::Comma(..) => self.next_token(),
1175 Token::Eof(span) => {
1176 self.record_error(ParserErr::new(span, "expected `,` or `}`"));
1177 break;
1178 }
1179 _ => {
1180 break;
1181 }
1182 };
1183 }
1184
1185 let span_end = match self.current_token() {
1187 Token::BraceR(span, ..) => {
1188 self.next_token();
1189 span.end
1190 }
1191 token => {
1192 self.record_error(ParserErr::new(
1193 *token.span(),
1194 format!("expected `}}` got {}", token),
1195 ));
1196
1197 return Ok(Expr::Dict(
1198 Span::from_begin_end(span_begin, Position::new(0, 0)),
1199 kvs.into_iter().collect(),
1200 ));
1201 }
1202 };
1203
1204 Ok(Expr::Dict(
1205 Span::from_begin_end(span_begin, span_end),
1206 kvs.into_iter().collect(),
1207 ))
1208 }
1209
1210 fn parse_neg_expr(&mut self) -> Result<Expr, ParserErr> {
1211 let span_token = match self.current_token() {
1213 Token::Sub(span, ..) => {
1214 self.next_token();
1215 span
1216 }
1217 token => {
1218 return Err(ParserErr::new(
1219 *token.span(),
1220 format!("expected `-` got {}", token),
1221 ));
1222 }
1223 };
1224
1225 let expr = self.parse_expr()?;
1227 let expr_span_end = expr.span().end;
1228
1229 Ok(Expr::App(
1231 Span::from_begin_end(span_token.begin, expr_span_end),
1232 Arc::new(Expr::Var(Var::with_span(span_token, "negate"))),
1233 Arc::new(expr),
1234 ))
1235 }
1236
1237 fn parse_lambda_expr(&mut self) -> Result<Expr, ParserErr> {
1239 let span_begin = match self.current_token() {
1241 Token::BackSlash(span, ..) => {
1242 self.next_token();
1243 span.begin
1244 }
1245 token => {
1246 return Err(ParserErr::new(
1247 *token.span(),
1248 format!("expected `\\` got {}", token),
1249 ));
1250 }
1251 };
1252
1253 let mut params = VecDeque::new();
1255 while let Token::Ident(..) | Token::ParenL(..) = self.current_token() {
1256 let (var, ann, span) = self.parse_lambda_param()?;
1257 params.push_back((span, var, ann));
1258 }
1259
1260 let mut constraints = Vec::new();
1261 if matches!(self.current_token(), Token::Where(..)) {
1262 self.next_token();
1263 constraints = self.parse_type_constraints()?;
1264 }
1265
1266 let _span_arrow = match self.current_token() {
1268 Token::ArrowR(span, ..) => {
1269 self.next_token();
1270 span
1271 }
1272 token => {
1273 return Err(ParserErr::new(
1274 *token.span(),
1275 format!("expected `->` got {}", token),
1276 ));
1277 }
1278 };
1279
1280 let mut body = self.parse_expr()?;
1282 let mut body_span_end = body.span().end;
1283 while let Some((param_span, param, ann)) = params.pop_back() {
1284 let lam_constraints = if params.is_empty() {
1285 std::mem::take(&mut constraints)
1286 } else {
1287 Vec::new()
1288 };
1289 body = Expr::Lam(
1290 Span::from_begin_end(param_span.begin, body_span_end),
1291 Scope::new_sync(),
1292 param,
1293 ann,
1294 lam_constraints,
1295 Arc::new(body),
1296 );
1297 body_span_end = body.span().end;
1298 }
1299 let body = body.with_span_begin(span_begin);
1301
1302 Ok(body)
1303 }
1304
1305 fn parse_lambda_param(&mut self) -> Result<(Var, Option<TypeExpr>, Span), ParserErr> {
1306 match self.current_token() {
1307 Token::Ident(name, span, ..) => {
1308 self.next_token();
1309 let mut ann = None;
1310 let mut param_span = span;
1311 if let Token::Colon(..) = self.current_token() {
1312 self.next_token();
1313 let ann_expr = self.parse_type_expr()?;
1314 param_span = Span::from_begin_end(span.begin, ann_expr.span().end);
1315 ann = Some(ann_expr);
1316 }
1317 Ok((Var::with_span(span, name), ann, param_span))
1318 }
1319 Token::ParenL(span_begin, ..) => {
1320 self.next_token();
1321 let (name, name_span) = self.expect_ident("parameter name")?;
1322 self.expect_colon()?;
1323 let ann = self.parse_type_expr()?;
1324 let span_end = self.expect_paren_r()?.end;
1325 Ok((
1326 Var::with_span(name_span, name),
1327 Some(ann),
1328 Span::from_begin_end(span_begin.begin, span_end),
1329 ))
1330 }
1331 token => Err(ParserErr::new(
1332 *token.span(),
1333 format!("expected lambda param got {}", token),
1334 )),
1335 }
1336 }
1337
1338 fn parse_type_constraints(&mut self) -> Result<Vec<TypeConstraint>, ParserErr> {
1339 let mut constraints = Vec::new();
1340 loop {
1341 let (class, _) = self.parse_name_ref_with_span("expected type class name")?;
1342
1343 let typ = self.parse_type_app()?;
1344 constraints.push(TypeConstraint::new(class, typ));
1345
1346 match self.current_token() {
1347 Token::Comma(..) => {
1348 self.next_token();
1349 continue;
1350 }
1351 _ => break,
1352 }
1353 }
1354 Ok(constraints)
1355 }
1356
1357 fn parse_let_expr(&mut self) -> Result<Expr, ParserErr> {
1359 let span_begin = match self.current_token() {
1361 Token::Let(span, ..) => {
1362 self.next_token();
1363 span.begin
1364 }
1365 token => {
1366 return Err(ParserErr::new(
1367 *token.span(),
1368 format!("expected `let` got {}", token),
1369 ));
1370 }
1371 };
1372
1373 let is_rec = if matches!(self.current_token(), Token::Rec(..)) {
1374 self.next_token();
1375 true
1376 } else {
1377 false
1378 };
1379
1380 if is_rec {
1381 let mut bindings = Vec::new();
1382 loop {
1383 let (pat, ann) = match (self.current_token(), self.peek_token(1)) {
1384 (Token::Ident(val, span, ..), Token::Colon(..)) => {
1385 self.next_token();
1386 self.next_token();
1387 let var = Var::with_span(span, val);
1388 let ann = Some(self.parse_type_expr()?);
1389 (Pattern::Var(var), ann)
1390 }
1391 _ => {
1392 let pat = self.parse_pattern()?;
1393 let mut ann = None;
1394 if let Token::Colon(..) = self.current_token() {
1395 self.next_token();
1396 ann = Some(self.parse_type_expr()?);
1397 }
1398 (pat, ann)
1399 }
1400 };
1401
1402 let var = match pat {
1403 Pattern::Var(var) => var,
1404 other => {
1405 return Err(ParserErr::new(
1406 *other.span(),
1407 "let rec only supports variable bindings".to_string(),
1408 ));
1409 }
1410 };
1411
1412 self.expect_assign()?;
1413 let def = Arc::new(self.parse_expr()?);
1414 bindings.push((var, ann, def));
1415
1416 match self.current_token() {
1417 Token::Comma(..) => {
1418 self.next_token();
1419 }
1420 Token::In(..) => break,
1421 token => {
1422 return Err(ParserErr::new(
1423 *token.span(),
1424 format!("expected `,` or `in` got {}", token),
1425 ));
1426 }
1427 }
1428 }
1429
1430 match self.current_token() {
1431 Token::In(..) => self.next_token(),
1432 token => {
1433 return Err(ParserErr::new(
1434 *token.span(),
1435 format!("expected `in` got {}", token),
1436 ));
1437 }
1438 };
1439
1440 let body = Arc::new(self.parse_expr()?);
1441 let span = Span::from_begin_end(span_begin, body.span().end);
1442 Ok(Expr::LetRec(span, bindings, body))
1443 } else {
1444 let mut decls = VecDeque::new();
1446 let is_pattern_start = |token: Token| {
1447 matches!(
1448 token,
1449 Token::Ident(..) | Token::ParenL(..) | Token::BracketL(..) | Token::BraceL(..)
1450 )
1451 };
1452 while is_pattern_start(self.current_token()) {
1453 let (pat, ann) = match (self.current_token(), self.peek_token(1)) {
1454 (Token::Ident(val, span, ..), Token::Colon(..)) => {
1455 self.next_token();
1456 self.next_token();
1457 let var = Var::with_span(span, val);
1458 let ann = Some(self.parse_type_expr()?);
1459 (Pattern::Var(var), ann)
1460 }
1461 _ => {
1462 let pat = self.parse_pattern()?;
1463 let mut ann = None;
1464 if let Token::Colon(..) = self.current_token() {
1465 self.next_token();
1466 ann = Some(self.parse_type_expr()?);
1467 }
1468 (pat, ann)
1469 }
1470 };
1471
1472 self.expect_assign()?;
1474 decls.push_back((pat, ann, self.parse_expr()?));
1476 match self.current_token() {
1478 Token::Comma(_span, ..) => {
1479 self.next_token();
1480 continue;
1481 }
1482 Token::In(..) => break,
1483 token => {
1484 return Err(ParserErr::new(
1485 *token.span(),
1486 format!("expected `,` or `in` got {}", token),
1487 ));
1488 }
1489 }
1490 }
1491
1492 let _span_arrow = match self.current_token() {
1494 Token::In(span, ..) => {
1495 self.next_token();
1496 span
1497 }
1498 token => {
1499 return Err(ParserErr::new(
1500 *token.span(),
1501 format!("expected `in` got {}", token),
1502 ));
1503 }
1504 };
1505
1506 let mut body = self.parse_expr()?;
1508 let mut body_span_end = body.span().end;
1509 while let Some((pat, ann, def)) = decls.pop_back() {
1510 match pat {
1511 Pattern::Var(var) => {
1512 body = Expr::Let(
1513 Span::from_begin_end(var.span.begin, body_span_end),
1514 var,
1515 ann,
1516 Arc::new(def),
1517 Arc::new(body),
1518 );
1519 }
1520 pat => {
1521 let def_expr = match ann {
1522 Some(ann) => {
1523 let span = Span::from_begin_end(def.span().begin, ann.span().end);
1524 Expr::Ann(span, Arc::new(def), ann)
1525 }
1526 None => def,
1527 };
1528 body = Expr::Match(
1529 Span::from_begin_end(pat.span().begin, body_span_end),
1530 Arc::new(def_expr),
1531 vec![(pat, Arc::new(body))],
1532 );
1533 }
1534 }
1535 body_span_end = body.span().end;
1536 }
1537 let body = body.with_span_begin(span_begin);
1540
1541 Ok(body)
1542 }
1543 }
1544
1545 fn parse_if_expr(&mut self) -> Result<Expr, ParserErr> {
1547 let span_begin = match self.current_token() {
1549 Token::If(span, ..) => {
1550 self.next_token();
1551 span.begin
1552 }
1553 token => {
1554 return Err(ParserErr::new(
1555 *token.span(),
1556 format!("expected `if` got {}", token),
1557 ));
1558 }
1559 };
1560
1561 let cond = self.parse_expr()?;
1563
1564 let _span_arrow = match self.current_token() {
1566 Token::Then(span, ..) => {
1567 self.next_token();
1568 span
1569 }
1570 token => {
1571 return Err(ParserErr::new(
1572 *token.span(),
1573 format!("expected `then` got {}", token),
1574 ));
1575 }
1576 };
1577
1578 let then = self.parse_expr()?;
1580
1581 let _span_arrow = match self.current_token() {
1583 Token::Else(span, ..) => {
1584 self.next_token();
1585 span
1586 }
1587 token => {
1588 return Err(ParserErr::new(
1589 *token.span(),
1590 format!("expected `else` got {}", token),
1591 ));
1592 }
1593 };
1594
1595 let r#else = self.parse_expr()?;
1597 let else_span_end = r#else.span().end;
1598
1599 Ok(Expr::Ite(
1600 Span::from_begin_end(span_begin, else_span_end),
1601 Arc::new(cond),
1602 Arc::new(then),
1603 Arc::new(r#else),
1604 ))
1605 }
1606
1607 fn parse_match_expr(&mut self) -> Result<Expr, ParserErr> {
1608 let span_begin = match self.current_token() {
1610 Token::Match(span, ..) => {
1611 self.next_token();
1612 span.begin
1613 }
1614 token => {
1615 return Err(ParserErr::new(
1616 *token.span(),
1617 format!("expected `match` got {}", token),
1618 ));
1619 }
1620 };
1621
1622 let scrutinee = self.parse_atom_expr()?;
1623 let mut arms = Vec::new();
1624 loop {
1625 match self.current_token() {
1626 Token::When(..) => {
1627 self.next_token();
1628 }
1629 token => {
1630 return Err(ParserErr::new(
1631 *token.span(),
1632 format!("expected `when` got {}", token),
1633 ));
1634 }
1635 }
1636
1637 let pattern = self.parse_pattern()?;
1638
1639 match self.current_token() {
1640 Token::ArrowR(..) => self.next_token(),
1641 token => {
1642 return Err(ParserErr::new(
1643 *token.span(),
1644 format!("expected `->` got {}", token),
1645 ));
1646 }
1647 }
1648
1649 let expr = self.parse_expr()?;
1650 arms.push((pattern, Arc::new(expr)));
1651
1652 match self.current_token() {
1653 Token::When(..) => continue,
1654 _ => break,
1655 }
1656 }
1657
1658 let span_end = arms
1659 .last()
1660 .map(|(_, expr)| expr.span().end)
1661 .unwrap_or_else(|| scrutinee.span().end);
1662
1663 Ok(Expr::Match(
1664 Span::from_begin_end(span_begin, span_end),
1665 Arc::new(scrutinee),
1666 arms,
1667 ))
1668 }
1669
1670 fn eof_for_slice(&self, slice: &[Token]) -> Span {
1671 slice.last().map(|t| *t.span()).unwrap_or(self.eof)
1672 }
1673
1674 fn parse_type_expr_slice(&self, slice: &[Token]) -> Result<TypeExpr, ParserErr> {
1675 if slice.is_empty() {
1676 return Err(ParserErr::new(self.eof, "expected type".to_string()));
1677 }
1678 let eof = self.eof_for_slice(slice);
1679 let tokens = Tokens {
1680 items: slice.to_vec(),
1681 eof,
1682 };
1683 let mut parser = Parser::new(tokens);
1684 let expr = parser.parse_type_expr()?;
1685 match parser.current_token() {
1686 Token::Eof(..) => Ok(expr),
1687 token => Err(ParserErr::new(
1688 *token.span(),
1689 format!("unexpected {} in type", token),
1690 )),
1691 }
1692 }
1693
1694 fn parse_type_app_slice(&self, slice: &[Token]) -> Result<TypeExpr, ParserErr> {
1695 if slice.is_empty() {
1696 return Err(ParserErr::new(self.eof, "expected type".to_string()));
1697 }
1698 let eof = self.eof_for_slice(slice);
1699 let tokens = Tokens {
1700 items: slice.to_vec(),
1701 eof,
1702 };
1703 let mut parser = Parser::new(tokens);
1704 let expr = parser.parse_type_app()?;
1705 match parser.current_token() {
1706 Token::Eof(..) => Ok(expr),
1707 token => Err(ParserErr::new(
1708 *token.span(),
1709 format!("unexpected {} in type", token),
1710 )),
1711 }
1712 }
1713
1714 fn parse_type_constraints_slice(
1715 &self,
1716 slice: &[Token],
1717 ) -> Result<Vec<TypeConstraint>, ParserErr> {
1718 if slice.is_empty() {
1719 return Err(ParserErr::new(
1720 self.eof,
1721 "expected type constraint".to_string(),
1722 ));
1723 }
1724 let eof = self.eof_for_slice(slice);
1725 let tokens = Tokens {
1726 items: slice.to_vec(),
1727 eof,
1728 };
1729 let mut parser = Parser::new(tokens);
1730 let constraints = parser.parse_type_constraints()?;
1731 match parser.current_token() {
1732 Token::Eof(..) => Ok(constraints),
1733 token => Err(ParserErr::new(
1734 *token.span(),
1735 format!("unexpected {} in type constraints", token),
1736 )),
1737 }
1738 }
1739
1740 fn parse_expr_slice(&self, slice: &[Token]) -> Result<Expr, ParserErr> {
1741 if slice.is_empty() {
1742 return Err(ParserErr::new(self.eof, "expected expression".to_string()));
1743 }
1744 let eof = self.eof_for_slice(slice);
1745 let tokens = Tokens {
1746 items: slice.to_vec(),
1747 eof,
1748 };
1749 let mut parser = Parser::new(tokens);
1750 let expr = parser.parse_expr()?;
1751 match parser.current_token() {
1752 Token::Eof(..) => Ok(expr),
1753 token => Err(ParserErr::new(
1754 *token.span(),
1755 format!("unexpected {} in expression", token),
1756 )),
1757 }
1758 }
1759
1760 fn parse_class_decl(&mut self, is_pub: bool) -> Result<ClassDecl, ParserErr> {
1761 let span_begin = match self.current_token() {
1762 Token::Class(span, ..) => {
1763 self.next_token();
1764 span.begin
1765 }
1766 token => {
1767 return Err(ParserErr::new(
1768 *token.span(),
1769 format!("expected `class` got {}", token),
1770 ));
1771 }
1772 };
1773
1774 let (name, name_span) = match self.current_token() {
1775 Token::Ident(name, span, ..) => {
1776 self.next_token_raw();
1777 (intern(&name), span)
1778 }
1779 token => {
1780 return Err(ParserErr::new(
1781 *token.span(),
1782 format!("expected class name got {}", token),
1783 ));
1784 }
1785 };
1786
1787 let class_indent = span_begin.column;
1788 let header_line = name_span.begin.line;
1789 let mut header_end = name_span.end;
1790
1791 let mut params = Vec::new();
1792 while let Some(Token::Ident(p, span, ..)) = self.tokens.get(self.token_cursor).cloned() {
1793 if span.begin.line != header_line {
1797 break;
1798 }
1799 header_end = header_end.max(span.end);
1800 params.push(intern(&p));
1801 self.next_token_raw();
1802 }
1803
1804 let mut supers = Vec::new();
1805 if let Some(Token::Le(span, ..)) = self.tokens.get(self.token_cursor).cloned() {
1806 if span.begin.line == header_line {
1807 self.next_token_raw();
1808 let start_idx = self.token_cursor;
1809 let end_idx = find_layout_header_clause_end(&self.tokens, start_idx, |t| {
1810 matches!(t, Token::Where(..))
1811 });
1812 supers = self.parse_type_constraints_slice(&self.tokens[start_idx..end_idx])?;
1813 self.token_cursor = end_idx;
1814 }
1815 if let Some(last) = supers.last() {
1816 header_end = header_end.max(last.typ.span().end);
1817 }
1818 }
1819
1820 let mut saw_where = false;
1829 let where_span = match self.current_token() {
1830 Token::Where(span, ..) => {
1831 self.next_token();
1832 header_end = header_end.max(span.end);
1833 saw_where = true;
1834 span
1835 }
1836 _ => Span::default(),
1837 };
1838
1839 let implicit_method_start = if saw_where {
1843 false
1844 } else {
1845 let token = self.current_token();
1846 let token_span = *token.span();
1847 let next = self.peek_token(1);
1848 token_span.begin.column > class_indent
1849 && matches!(next, Token::Colon(..))
1850 && Self::is_value_name_token(&token)
1851 };
1852 let has_method_block = saw_where || implicit_method_start;
1853 let block_indent = if has_method_block {
1854 match self.current_token() {
1855 Token::Ident(_, span, ..) => Some(span.begin.column),
1856 token => Self::operator_token_name(&token).map(|(_, span)| span.begin.column),
1857 }
1858 } else {
1859 None
1860 };
1861
1862 let methods = self.parse_layout_block(has_method_block, block_indent, |parser| {
1863 let (m_name, _name_span) = parser.parse_value_name()?;
1864 parser.expect_colon()?;
1865
1866 let start_idx = parser.token_cursor;
1867 let end_idx =
1868 find_layout_expr_end(&parser.tokens, start_idx, block_indent, |t, next| {
1869 matches!(next, Token::Colon(..)) && Self::is_value_name_token(t)
1870 });
1871 let typ = parser.parse_type_expr_slice(&parser.tokens[start_idx..end_idx])?;
1872 parser.token_cursor = end_idx;
1873 parser.skip_newlines();
1874 Ok(ClassMethodSig { name: m_name, typ })
1875 })?;
1876
1877 let span_end = methods
1878 .last()
1879 .map(|m| m.typ.span().end)
1880 .or_else(|| supers.last().map(|s| s.typ.span().end))
1881 .unwrap_or(header_end.max(where_span.end));
1882
1883 Ok(ClassDecl {
1884 span: Span::from_begin_end(span_begin, span_end),
1885 is_pub,
1886 name,
1887 params,
1888 supers,
1889 methods,
1890 })
1891 }
1892
1893 fn parse_instance_decl(&mut self, is_pub: bool) -> Result<InstanceDecl, ParserErr> {
1894 let span_begin = match self.current_token() {
1895 Token::Instance(span, ..) => {
1896 self.next_token();
1897 span.begin
1898 }
1899 token => {
1900 return Err(ParserErr::new(
1901 *token.span(),
1902 format!("expected `instance` got {}", token),
1903 ));
1904 }
1905 };
1906
1907 let (class_ref, class_span) = self.parse_name_ref_with_span("expected class name")?;
1908 let class = class_ref.to_dotted_symbol();
1909
1910 let instance_indent = span_begin.column;
1911 let header_line = class_span.begin.line;
1912
1913 let start_idx = self.token_cursor;
1914 let end_idx = find_layout_header_clause_end(&self.tokens, start_idx, |t| {
1915 matches!(t, Token::Le(..) | Token::Where(..))
1916 });
1917 if end_idx == start_idx {
1918 let span = self
1919 .tokens
1920 .get(start_idx)
1921 .map(|t| *t.span())
1922 .unwrap_or(self.eof);
1923 return Err(ParserErr::new(span, "expected type".to_string()));
1924 }
1925 let head = self.parse_type_app_slice(&self.tokens[start_idx..end_idx])?;
1926 self.token_cursor = end_idx;
1927 let mut header_end = head.span().end;
1928
1929 let mut context = Vec::new();
1930 if let Some(Token::Le(span, ..)) = self.tokens.get(self.token_cursor).cloned()
1931 && span.begin.line == header_line
1932 {
1933 self.next_token_raw();
1934 let start_idx = self.token_cursor;
1935 let end_idx = find_layout_header_clause_end(&self.tokens, start_idx, |t| {
1936 matches!(t, Token::Where(..))
1937 });
1938 context = self.parse_type_constraints_slice(&self.tokens[start_idx..end_idx])?;
1939 self.token_cursor = end_idx;
1940 if let Some(last) = context.last() {
1941 header_end = header_end.max(last.typ.span().end);
1942 }
1943 }
1944
1945 let mut saw_where = false;
1951 let where_span = match self.current_token() {
1952 Token::Where(span, ..) => {
1953 self.next_token();
1954 header_end = header_end.max(span.end);
1955 saw_where = true;
1956 span
1957 }
1958 _ => Span::default(),
1959 };
1960
1961 let has_method_block = if saw_where {
1964 true
1965 } else {
1966 let token = self.current_token();
1967 let token_span = *token.span();
1968 let next = self.peek_token(1);
1969 token_span.begin.column > instance_indent
1970 && matches!(next, Token::Assign(..))
1971 && Self::is_value_name_token(&token)
1972 };
1973
1974 let block_indent = if has_method_block {
1975 match self.current_token() {
1976 Token::Ident(_, span, ..) => Some(span.begin.column),
1977 token => Self::operator_token_name(&token).map(|(_, span)| span.begin.column),
1978 }
1979 } else {
1980 None
1981 };
1982
1983 let methods = self.parse_layout_block(has_method_block, block_indent, |parser| {
1984 let (name, _name_span) = parser.parse_value_name()?;
1985 parser.expect_assign()?;
1986
1987 let start_idx = parser.token_cursor;
1988 let end_idx =
1989 find_layout_expr_end(&parser.tokens, start_idx, block_indent, |t, next| {
1990 matches!(next, Token::Assign(..)) && Self::is_value_name_token(t)
1991 });
1992 let body = parser.parse_expr_slice(&parser.tokens[start_idx..end_idx])?;
1993 parser.token_cursor = end_idx;
1994 parser.skip_newlines();
1995
1996 Ok(InstanceMethodImpl {
1997 name,
1998 body: Arc::new(body),
1999 })
2000 })?;
2001
2002 let span_end = methods
2003 .last()
2004 .map(|m| m.body.span().end)
2005 .or_else(|| context.last().map(|c| c.typ.span().end))
2006 .unwrap_or(header_end.max(where_span.end));
2007
2008 Ok(InstanceDecl {
2009 span: Span::from_begin_end(span_begin, span_end),
2010 is_pub,
2011 class,
2012 head,
2013 context,
2014 methods,
2015 })
2016 }
2017
2018 fn parse_fn_decl(&mut self, is_pub: bool) -> Result<FnDecl, ParserErr> {
2019 let span_begin = match self.current_token() {
2020 Token::Fn(span, ..) => {
2021 self.next_token();
2022 span.begin
2023 }
2024 token => {
2025 return Err(ParserErr::new(
2026 *token.span(),
2027 format!("expected `fn` got {}", token),
2028 ));
2029 }
2030 };
2031
2032 let (name, name_span) = match self.current_token() {
2033 Token::Ident(name, span, ..) => {
2034 self.next_token();
2035 (name, span)
2036 }
2037 token => {
2038 return Err(ParserErr::new(
2039 *token.span(),
2040 format!("expected function name got {}", token),
2041 ));
2042 }
2043 };
2044
2045 let name_var = Var::with_span(name_span, name);
2046 let mut params: Vec<(Var, TypeExpr)> = Vec::new();
2047
2048 if matches!(self.current_token(), Token::Colon(..)) {
2056 self.next_token();
2057
2058 let sig_start = self.token_cursor;
2060 let sig_end = self
2061 .find_token_at_depth0(sig_start, self.tokens.len(), |t| {
2062 matches!(t, Token::Where(..) | Token::Assign(..))
2063 })
2064 .ok_or_else(|| ParserErr::new(self.eof, "expected `=`".to_string()))?;
2065 let sig = self.parse_type_expr_slice(&self.tokens[sig_start..sig_end])?;
2066 self.token_cursor = sig_end;
2067
2068 let mut constraints = Vec::new();
2069 if matches!(self.current_token(), Token::Where(..)) {
2070 self.next_token();
2071 constraints = self.parse_type_constraints()?;
2072 }
2073
2074 self.expect_assign()?;
2076
2077 let body_start = self.token_cursor;
2079 let body_end = self.find_dedent_end(body_start, span_begin.column)?;
2080 let body_expr = self.parse_expr_slice(&self.tokens[body_start..body_end])?;
2081 self.token_cursor = body_end;
2082 let body = Arc::new(body_expr);
2083 let span_end = body.span().end;
2084
2085 let mut param_tys = Vec::new();
2088 let mut cur = sig;
2089 let ret = loop {
2090 match cur {
2091 TypeExpr::Fun(_, arg, next_ret) => {
2092 param_tys.push(*arg);
2093 cur = *next_ret;
2094 }
2095 other => break other,
2096 }
2097 };
2098 if param_tys.is_empty() {
2099 return Err(ParserErr::new(
2100 *ret.span(),
2101 "expected function type after `:`; use `let` for values".to_string(),
2102 ));
2103 }
2104
2105 let arity = param_tys.len();
2106 let mut body_constraints = Vec::new();
2107 let (params, body) = if matches!(body.as_ref(), Expr::Lam(..)) {
2108 let mut lam_params: Vec<Var> = Vec::new();
2109 let mut cur = body.clone();
2110 while matches!(cur.as_ref(), Expr::Lam(..)) {
2111 let Expr::Lam(_span, _scope, param, _ann, lam_constraints, next) = cur.as_ref()
2112 else {
2113 break;
2114 };
2115 if !lam_constraints.is_empty() {
2116 body_constraints.extend(lam_constraints.iter().cloned());
2117 }
2118 lam_params.push(param.clone());
2119 cur = next.clone();
2120 }
2121
2122 if lam_params.len() != arity {
2123 return Err(ParserErr::new(
2124 *body.span(),
2125 format!(
2126 "lambda has {} parameter(s) but signature expects {}",
2127 lam_params.len(),
2128 arity
2129 ),
2130 ));
2131 }
2132
2133 let params: Vec<(Var, TypeExpr)> = lam_params.into_iter().zip(param_tys).collect();
2134 (params, cur)
2135 } else {
2136 let var_span = *body.span();
2138 let vars: Vec<Var> = (0..arity)
2139 .map(|i| Var::with_span(var_span, format!("_arg{i}")))
2140 .collect();
2141
2142 let mut applied = body.clone();
2143 for v in &vars {
2144 applied = Arc::new(Expr::App(
2145 Span::from_begin_end(applied.span().begin, applied.span().end),
2146 applied,
2147 Arc::new(Expr::Var(v.clone())),
2148 ));
2149 }
2150
2151 let params: Vec<(Var, TypeExpr)> = vars.into_iter().zip(param_tys).collect();
2152 (params, applied)
2153 };
2154
2155 constraints.extend(body_constraints);
2156
2157 return Ok(FnDecl {
2158 span: Span::from_begin_end(span_begin, span_end),
2159 is_pub,
2160 name: name_var,
2161 params,
2162 ret,
2163 constraints,
2164 body,
2165 });
2166 }
2167
2168 let is_named_param_head = |token: &Token, next: &Token| {
2169 matches!(token, Token::Ident(..)) && matches!(next, Token::Colon(..))
2170 };
2171 let is_paren_param_head = |token: &Token, next: &Token, next2: &Token| {
2172 matches!(token, Token::ParenL(..))
2173 && matches!(next, Token::Ident(..))
2174 && matches!(next2, Token::Colon(..))
2175 };
2176
2177 if matches!(self.current_token(), Token::ParenL(..)) {
2186 if self.paren_group_has_top_level_comma(self.token_cursor)
2188 || matches!(self.peek_token(1), Token::ParenR(..))
2189 {
2190 params = self.parse_legacy_param_group()?;
2191
2192 match self.current_token() {
2194 Token::ArrowR(..) => self.next_token(),
2195 token => {
2196 return Err(ParserErr::new(
2197 *token.span(),
2198 format!("expected `->` got {}", token),
2199 ));
2200 }
2201 }
2202 }
2203 }
2204
2205 if params.is_empty() {
2208 loop {
2209 let tok = self.current_token();
2210 let next = self.peek_token(1);
2211 let next2 = self.peek_token(2);
2212 if is_paren_param_head(&tok, &next, &next2) {
2213 self.next_token(); let (param_name, param_span) = self.expect_ident("parameter name")?;
2216 self.expect_colon()?;
2217
2218 let ty_start = self.token_cursor;
2220 let rparen_idx = self
2221 .find_token_at_depth0(ty_start, self.tokens.len(), |t| {
2222 matches!(t, Token::ParenR(..))
2223 })
2224 .ok_or_else(|| ParserErr::new(self.eof, "expected `)`".to_string()))?;
2225 let ann = self.parse_type_expr_slice(&self.tokens[ty_start..rparen_idx])?;
2226 self.token_cursor = rparen_idx;
2227
2228 let _ = self.expect_paren_r()?;
2229
2230 params.push((Var::with_span(param_span, param_name), ann));
2231 } else if is_named_param_head(&tok, &next) {
2232 let (param_name, param_span) = self.expect_ident("parameter name")?;
2234
2235 self.expect_colon()?;
2236
2237 let ty_start = self.token_cursor;
2241 let mut depth = 0usize;
2242 let mut arrow_idx = None;
2243 let mut stop_span = None;
2244 for i in ty_start..self.tokens.len() {
2245 match self.tokens[i] {
2246 Token::ParenL(..) | Token::BracketL(..) | Token::BraceL(..) => {
2247 depth += 1
2248 }
2249 Token::ParenR(..) | Token::BracketR(..) | Token::BraceR(..) => {
2250 depth = depth.saturating_sub(1)
2251 }
2252 Token::ArrowR(..) if depth == 0 => {
2253 arrow_idx = Some(i);
2254 break;
2255 }
2256 Token::Assign(span, ..) | Token::Where(span, ..) if depth == 0 => {
2257 stop_span = Some(span);
2258 break;
2259 }
2260 _ => {}
2261 }
2262 }
2263 let Some(arrow_idx) = arrow_idx else {
2264 let span = stop_span.unwrap_or(self.eof);
2265 return Err(ParserErr::new(
2266 span,
2267 "expected `->` after parameter type".to_string(),
2268 ));
2269 };
2270 let ann = self.parse_type_expr_slice(&self.tokens[ty_start..arrow_idx])?;
2271 self.token_cursor = arrow_idx;
2272 params.push((Var::with_span(param_span, param_name), ann));
2273 } else {
2274 return Err(ParserErr::new(
2275 *tok.span(),
2276 format!("expected `(` or parameter name got {}", tok),
2277 ));
2278 }
2279
2280 match self.current_token() {
2282 Token::ArrowR(..) => self.next_token(),
2283 token => {
2284 return Err(ParserErr::new(
2285 *token.span(),
2286 format!("expected `->` got {}", token),
2287 ));
2288 }
2289 }
2290
2291 let tok = self.current_token();
2293 let next = self.peek_token(1);
2294 let next2 = self.peek_token(2);
2295 if is_paren_param_head(&tok, &next, &next2) || is_named_param_head(&tok, &next) {
2296 continue;
2297 }
2298 break;
2299 }
2300 }
2301
2302 let ret_start = self.token_cursor;
2304 let assign_idx = self
2305 .find_token_at_depth0(ret_start, self.tokens.len(), |t| {
2306 matches!(t, Token::Assign(..))
2307 })
2308 .ok_or_else(|| {
2309 ParserErr::new(self.eof, "expected `=` in function declaration".to_string())
2310 })?;
2311
2312 let ret_end = self
2313 .find_token_at_depth0(ret_start, assign_idx, |t| matches!(t, Token::Where(..)))
2314 .unwrap_or(assign_idx);
2315 let ret = self.parse_type_expr_slice(&self.tokens[ret_start..ret_end])?;
2316 self.token_cursor = ret_end;
2317
2318 let mut constraints = Vec::new();
2319 if matches!(self.current_token(), Token::Where(..)) {
2320 self.next_token();
2321 constraints = self.parse_type_constraints()?;
2322 }
2323
2324 self.expect_assign()?;
2326
2327 let body_start = self.token_cursor;
2329 let body_end = self.find_same_line_end(body_start)?;
2330 let body = self.parse_expr_slice(&self.tokens[body_start..body_end])?;
2331 self.token_cursor = body_end;
2332 let span_end = body.span().end;
2333
2334 Ok(FnDecl {
2335 span: Span::from_begin_end(span_begin, span_end),
2336 is_pub,
2337 name: name_var,
2338 params,
2339 ret,
2340 constraints,
2341 body: Arc::new(body),
2342 })
2343 }
2344
2345 fn parse_declare_fn_decl_toplevel(&mut self, is_pub: bool) -> Result<DeclareFnDecl, ParserErr> {
2346 let start_idx = self.token_cursor;
2347 let end_idx = self.find_same_line_end(start_idx)?;
2349
2350 let eof = self
2351 .tokens
2352 .get(end_idx.saturating_sub(1))
2353 .map(|t| *t.span())
2354 .unwrap_or(self.eof);
2355 let tokens = Tokens {
2356 items: self.tokens[start_idx..end_idx].to_vec(),
2357 eof,
2358 };
2359 let mut parser = Parser::new(tokens);
2360 let decl = parser.parse_declare_fn_decl(is_pub)?;
2361 match parser.current_token() {
2362 Token::Eof(..) => {}
2363 token => {
2364 return Err(ParserErr::new(
2365 *token.span(),
2366 format!("unexpected {} in declaration", token),
2367 ));
2368 }
2369 }
2370
2371 self.token_cursor = end_idx;
2372 self.skip_newlines();
2373 Ok(decl)
2374 }
2375
2376 fn parse_declare_fn_decl(&mut self, is_pub: bool) -> Result<DeclareFnDecl, ParserErr> {
2377 let span_begin = match self.current_token() {
2378 Token::Declare(span, ..) => {
2379 self.next_token();
2380 span.begin
2381 }
2382 token => {
2383 return Err(ParserErr::new(
2384 *token.span(),
2385 format!("expected `declare` got {}", token),
2386 ));
2387 }
2388 };
2389
2390 match self.current_token() {
2391 Token::Fn(..) => self.next_token(),
2392 token => {
2393 return Err(ParserErr::new(
2394 *token.span(),
2395 format!("expected `fn` got {}", token),
2396 ));
2397 }
2398 }
2399
2400 let (name, name_span) = match self.current_token() {
2401 Token::Ident(name, span, ..) => {
2402 self.next_token();
2403 (name, span)
2404 }
2405 token => {
2406 return Err(ParserErr::new(
2407 *token.span(),
2408 format!("expected function name got {}", token),
2409 ));
2410 }
2411 };
2412
2413 let name_var = Var::with_span(name_span, name);
2414 let mut params: Vec<(Var, TypeExpr)> = Vec::new();
2415
2416 if matches!(self.current_token(), Token::Colon(..)) {
2419 self.next_token();
2420 }
2421
2422 let is_named_param_head = |token: &Token, next: &Token| {
2423 matches!(token, Token::Ident(..)) && matches!(next, Token::Colon(..))
2424 };
2425 let is_paren_param_head = |token: &Token, next: &Token, next2: &Token| {
2426 matches!(token, Token::ParenL(..))
2427 && matches!(next, Token::Ident(..))
2428 && matches!(next2, Token::Colon(..))
2429 };
2430
2431 let tok = self.current_token();
2435 let next = self.peek_token(1);
2436 let next2 = self.peek_token(2);
2437 let mut use_named_params =
2438 is_named_param_head(&tok, &next) || is_paren_param_head(&tok, &next, &next2);
2439
2440 if !use_named_params && matches!(tok, Token::ParenL(..)) {
2441 if matches!(next, Token::ParenR(..)) {
2443 use_named_params = true;
2444 } else {
2445 if self.paren_group_has_top_level_colon(self.token_cursor) {
2447 use_named_params = true;
2448 }
2449 }
2450 }
2451
2452 if !use_named_params {
2453 let sig_start = self.token_cursor;
2455 let stop_idx = self.find_token_at_depth0(sig_start, self.tokens.len(), |t| {
2456 matches!(t, Token::Where(..) | Token::Assign(..))
2457 });
2458 let sig_end = match stop_idx {
2459 Some(i) => match self.tokens[i] {
2460 Token::Where(..) => i,
2461 Token::Assign(span, ..) => {
2462 return Err(ParserErr::new(
2463 span,
2464 "declare fn cannot have a body; use `fn`".to_string(),
2465 ));
2466 }
2467 _ => i,
2468 },
2469 None => self.tokens.len(),
2470 };
2471 let sig = self.parse_type_expr_slice(&self.tokens[sig_start..sig_end])?;
2472 self.token_cursor = sig_end;
2473
2474 let mut constraints = Vec::new();
2475 if matches!(self.current_token(), Token::Where(..)) {
2476 self.next_token();
2477 constraints = self.parse_type_constraints()?;
2478 }
2479
2480 let mut param_tys = Vec::new();
2483 let mut cur = sig;
2484 let ret = loop {
2485 match cur {
2486 TypeExpr::Fun(_, arg, next_ret) => {
2487 param_tys.push(*arg);
2488 cur = *next_ret;
2489 }
2490 other => break other,
2491 }
2492 };
2493 params = param_tys
2494 .into_iter()
2495 .enumerate()
2496 .map(|(i, ann)| (Var::with_span(*ann.span(), format!("_arg{i}")), ann))
2497 .collect();
2498
2499 let span_end = constraints
2500 .last()
2501 .map(|c| c.typ.span().end)
2502 .unwrap_or(ret.span().end);
2503 return Ok(DeclareFnDecl {
2504 span: Span::from_begin_end(span_begin, span_end),
2505 is_pub,
2506 name: name_var,
2507 params,
2508 ret,
2509 constraints,
2510 });
2511 }
2512
2513 if matches!(self.current_token(), Token::ParenL(..)) {
2520 if self.paren_group_has_top_level_comma(self.token_cursor)
2522 || matches!(self.peek_token(1), Token::ParenR(..))
2523 {
2524 params = self.parse_legacy_param_group()?;
2525
2526 match self.current_token() {
2528 Token::ArrowR(..) => self.next_token(),
2529 token => {
2530 return Err(ParserErr::new(
2531 *token.span(),
2532 format!("expected `->` got {}", token),
2533 ));
2534 }
2535 }
2536 }
2537 }
2538
2539 if params.is_empty() {
2542 loop {
2543 let tok = self.current_token();
2544 let next = self.peek_token(1);
2545 let next2 = self.peek_token(2);
2546 if is_paren_param_head(&tok, &next, &next2) {
2547 self.next_token(); let (param_name, param_span) = self.expect_ident("parameter name")?;
2550 self.expect_colon()?;
2551
2552 let ty_start = self.token_cursor;
2554 let rparen_idx = self
2555 .find_token_at_depth0(ty_start, self.tokens.len(), |t| {
2556 matches!(t, Token::ParenR(..))
2557 })
2558 .ok_or_else(|| ParserErr::new(self.eof, "expected `)`".to_string()))?;
2559 let ann = self.parse_type_expr_slice(&self.tokens[ty_start..rparen_idx])?;
2560 self.token_cursor = rparen_idx;
2561
2562 let _ = self.expect_paren_r()?;
2563
2564 params.push((Var::with_span(param_span, param_name), ann));
2565 } else if is_named_param_head(&tok, &next) {
2566 let (param_name, param_span) = self.expect_ident("parameter name")?;
2568 self.expect_colon()?;
2569
2570 let ty_start = self.token_cursor;
2574 let mut depth = 0usize;
2575 let mut arrow_idx = None;
2576 let mut stop_span = None;
2577 for i in ty_start..self.tokens.len() {
2578 match self.tokens[i] {
2579 Token::ParenL(..) | Token::BracketL(..) | Token::BraceL(..) => {
2580 depth += 1
2581 }
2582 Token::ParenR(..) | Token::BracketR(..) | Token::BraceR(..) => {
2583 depth = depth.saturating_sub(1)
2584 }
2585 Token::ArrowR(..) if depth == 0 => {
2586 arrow_idx = Some(i);
2587 break;
2588 }
2589 Token::Where(span, ..) if depth == 0 => {
2590 stop_span = Some(span);
2591 break;
2592 }
2593 _ => {}
2594 }
2595 }
2596 let Some(arrow_idx) = arrow_idx else {
2597 let span = stop_span.unwrap_or(self.eof);
2598 return Err(ParserErr::new(
2599 span,
2600 "expected `->` after parameter type".to_string(),
2601 ));
2602 };
2603 let ann = self.parse_type_expr_slice(&self.tokens[ty_start..arrow_idx])?;
2604 self.token_cursor = arrow_idx;
2605 params.push((Var::with_span(param_span, param_name), ann));
2606 } else {
2607 return Err(ParserErr::new(
2608 *tok.span(),
2609 format!("expected `(` or parameter name got {}", tok),
2610 ));
2611 }
2612
2613 match self.current_token() {
2615 Token::ArrowR(..) => self.next_token(),
2616 token => {
2617 return Err(ParserErr::new(
2618 *token.span(),
2619 format!("expected `->` got {}", token),
2620 ));
2621 }
2622 }
2623
2624 let tok = self.current_token();
2626 let next = self.peek_token(1);
2627 let next2 = self.peek_token(2);
2628 if is_paren_param_head(&tok, &next, &next2) || is_named_param_head(&tok, &next) {
2629 continue;
2630 }
2631 break;
2632 }
2633 }
2634
2635 let ret_start = self.token_cursor;
2637 let stop_idx = self.find_token_at_depth0(ret_start, self.tokens.len(), |t| {
2638 matches!(t, Token::Where(..) | Token::Assign(..))
2639 });
2640 let ret_end = match stop_idx {
2641 Some(i) => match self.tokens[i] {
2642 Token::Where(..) => i,
2643 Token::Assign(span, ..) => {
2644 return Err(ParserErr::new(
2645 span,
2646 "declare fn cannot have a body; use `fn`".to_string(),
2647 ));
2648 }
2649 _ => i,
2650 },
2651 None => self.tokens.len(),
2652 };
2653 let ret = self.parse_type_expr_slice(&self.tokens[ret_start..ret_end])?;
2654 self.token_cursor = ret_end;
2655
2656 let mut constraints = Vec::new();
2657 if matches!(self.current_token(), Token::Where(..)) {
2658 self.next_token();
2659 constraints = self.parse_type_constraints()?;
2660 }
2661
2662 let span_end = constraints
2663 .last()
2664 .map(|c| c.typ.span().end)
2665 .unwrap_or(ret.span().end);
2666 Ok(DeclareFnDecl {
2667 span: Span::from_begin_end(span_begin, span_end),
2668 is_pub,
2669 name: name_var,
2670 params,
2671 ret,
2672 constraints,
2673 })
2674 }
2675
2676 fn parse_import_decl(&mut self, is_pub: bool) -> Result<ImportDecl, ParserErr> {
2677 let span_begin = match self.current_token() {
2678 Token::Import(span, ..) => {
2679 self.next_token();
2680 span.begin
2681 }
2682 token => {
2683 return Err(ParserErr::new(
2684 *token.span(),
2685 format!("expected `import` got {}", token),
2686 ));
2687 }
2688 };
2689
2690 let (path, mut span_end, default_alias) = match self.current_token() {
2691 Token::HttpsUrl(url, span, ..) => {
2692 let url = url.clone();
2693 self.next_token();
2694 let (base_url, sha) = match url.split_once('#') {
2695 Some((a, b)) if !b.is_empty() => (a.to_string(), Some(b.to_string())),
2696 _ => (url, None),
2697 };
2698 let alias = base_url
2699 .rsplit('/')
2700 .next()
2701 .unwrap_or("")
2702 .trim_end_matches(".rex")
2703 .to_string();
2704 (
2705 ImportPath::Remote { url: base_url, sha },
2706 span.end,
2707 if alias.is_empty() {
2708 None
2709 } else {
2710 Some(intern(&alias))
2711 },
2712 )
2713 }
2714 Token::Dot(..) | Token::DotDot(..) => {
2715 let (mut segs, end) = self.parse_relative_import_segments()?;
2716
2717 let sha = if matches!(self.current_token(), Token::HashTag(..)) {
2718 self.next_token();
2719 match self.current_token() {
2720 Token::Ident(s, span, ..) => {
2721 self.next_token();
2722 Some((s.clone(), span.end))
2723 }
2724 Token::Int(n, span, ..) => {
2725 self.next_token();
2726 Some((n.to_string(), span.end))
2727 }
2728 token => {
2729 return Err(ParserErr::new(
2730 *token.span(),
2731 format!("expected sha token got {}", token),
2732 ));
2733 }
2734 }
2735 } else {
2736 None
2737 };
2738 let mut end = end;
2739 let sha = sha.map(|(sha, sha_end)| {
2740 end = end.max(sha_end);
2741 sha
2742 });
2743 let default_alias = segs.last().cloned();
2744 if segs.is_empty() {
2745 return Err(ParserErr::new(
2746 *self.current_token().span(),
2747 "relative import must include a library path",
2748 ));
2749 }
2750 (
2751 ImportPath::Local {
2752 segments: std::mem::take(&mut segs),
2753 sha,
2754 },
2755 end,
2756 default_alias,
2757 )
2758 }
2759 Token::Ident(..) => {
2760 let mut segs: Vec<Symbol> = Vec::new();
2761 let (first, first_span) = match self.current_token() {
2762 Token::Ident(name, span, ..) => (intern(&name), span),
2763 token => {
2764 return Err(ParserErr::new(
2765 *token.span(),
2766 format!("expected library path segment got {}", token),
2767 ));
2768 }
2769 };
2770 let mut end = first_span.end;
2771 segs.push(first);
2772 self.next_token();
2773
2774 while matches!(self.current_token(), Token::Dot(..)) {
2775 self.next_token();
2776 let (seg, seg_span) = match self.current_token() {
2777 Token::Ident(name, span, ..) => (intern(&name), span),
2778 token => {
2779 return Err(ParserErr::new(
2780 *token.span(),
2781 format!("expected library path segment got {}", token),
2782 ));
2783 }
2784 };
2785 segs.push(seg);
2786 end = seg_span.end;
2787 self.next_token();
2788 }
2789
2790 let sha = if matches!(self.current_token(), Token::HashTag(..)) {
2791 self.next_token();
2792 match self.current_token() {
2793 Token::Ident(s, span, ..) => {
2794 self.next_token();
2795 end = end.max(span.end);
2796 Some(s.clone())
2797 }
2798 Token::Int(n, span, ..) => {
2799 self.next_token();
2800 end = end.max(span.end);
2801 Some(n.to_string())
2802 }
2803 token => {
2804 return Err(ParserErr::new(
2805 *token.span(),
2806 format!("expected sha token got {}", token),
2807 ));
2808 }
2809 }
2810 } else {
2811 None
2812 };
2813 let default_alias = segs.last().cloned();
2814 (
2815 ImportPath::Local {
2816 segments: segs,
2817 sha,
2818 },
2819 end,
2820 default_alias,
2821 )
2822 }
2823 token => {
2824 return Err(ParserErr::new(
2825 *token.span(),
2826 format!("expected library path got {}", token),
2827 ));
2828 }
2829 };
2830
2831 let clause = if matches!(self.current_token(), Token::ParenL(..)) {
2832 self.next_token();
2833 if matches!(self.current_token(), Token::Mul(..)) {
2834 self.next_token();
2835 let end = match self.current_token() {
2836 Token::ParenR(span, ..) => {
2837 self.next_token();
2838 span.end
2839 }
2840 token => {
2841 return Err(ParserErr::new(
2842 *token.span(),
2843 format!("expected `)` got {}", token),
2844 ));
2845 }
2846 };
2847 span_end = span_end.max(end);
2848 Some(ImportClause::All)
2849 } else {
2850 let mut items: Vec<ImportItem> = Vec::new();
2851 let mut local_names: HashSet<Symbol> = HashSet::new();
2852 loop {
2853 let (name, item_span) = self.parse_value_name()?;
2854 let mut item_end = item_span.end;
2855 let alias = if matches!(self.current_token(), Token::As(..)) {
2856 self.next_token();
2857 match self.current_token() {
2858 Token::Ident(alias, alias_span, ..) => {
2859 self.next_token();
2860 item_end = alias_span.end;
2861 Some(intern(&alias))
2862 }
2863 token => {
2864 return Err(ParserErr::new(
2865 *token.span(),
2866 format!("expected alias name got {}", token),
2867 ));
2868 }
2869 }
2870 } else {
2871 None
2872 };
2873
2874 let local_name = alias.clone().unwrap_or_else(|| name.clone());
2875 if local_names.contains(&local_name) {
2876 return Err(ParserErr::new(
2877 Span::from_begin_end(item_span.begin, item_end),
2878 format!("duplicate imported name `{local_name}`"),
2879 ));
2880 }
2881 local_names.insert(local_name);
2882 items.push(ImportItem { name, alias });
2883
2884 match self.current_token() {
2885 Token::Comma(..) => {
2886 self.next_token();
2887 }
2888 Token::ParenR(span, ..) => {
2889 self.next_token();
2890 span_end = span_end.max(span.end.max(item_end));
2891 break;
2892 }
2893 token => {
2894 return Err(ParserErr::new(
2895 *token.span(),
2896 format!("expected `,` or `)` got {}", token),
2897 ));
2898 }
2899 }
2900 }
2901 Some(ImportClause::Items(items))
2902 }
2903 } else {
2904 None
2905 };
2906
2907 let alias = if matches!(self.current_token(), Token::As(..)) {
2908 if clause.is_some() {
2909 let span = *self.current_token().span();
2910 return Err(ParserErr::new(
2911 span,
2912 "cannot combine `as <alias>` with import clause `(...)`".to_string(),
2913 ));
2914 }
2915 self.next_token();
2916 match self.current_token() {
2917 Token::Ident(name, span, ..) => {
2918 self.next_token();
2919 span_end = span_end.max(span.end);
2920 intern(&name)
2921 }
2922 token => {
2923 return Err(ParserErr::new(
2924 *token.span(),
2925 format!("expected alias name got {}", token),
2926 ));
2927 }
2928 }
2929 } else {
2930 default_alias
2931 .or_else(|| clause.as_ref().map(|_| intern("_")))
2932 .ok_or_else(|| {
2933 ParserErr::new(
2934 Span::from_begin_end(span_begin, span_end),
2935 "import requires `as <alias>`".to_string(),
2936 )
2937 })?
2938 };
2939
2940 self.skip_newlines();
2941 Ok(ImportDecl {
2942 span: Span::from_begin_end(span_begin, span_end),
2943 is_pub,
2944 path,
2945 alias,
2946 clause,
2947 })
2948 }
2949
2950 fn parse_relative_import_segments(&mut self) -> Result<(Vec<Symbol>, Position), ParserErr> {
2951 let mut segments: Vec<Symbol> = Vec::new();
2952
2953 loop {
2954 if matches!(self.current_token(), Token::DotDot(..)) {
2955 self.next_token();
2956 segments.push(intern("super"));
2957 } else {
2958 match self.current_token() {
2959 Token::Dot(..) => self.next_token(),
2960 token => {
2961 return Err(ParserErr::new(
2962 *token.span(),
2963 "expected `.` or `..` in relative import path",
2964 ));
2965 }
2966 }
2967 }
2968
2969 match self.current_token() {
2970 Token::Div(..) => self.next_token(),
2971 token => {
2972 return Err(ParserErr::new(
2973 *token.span(),
2974 "expected `/` in relative import path",
2975 ));
2976 }
2977 }
2978
2979 if !matches!(self.current_token(), Token::Dot(..) | Token::DotDot(..)) {
2980 break;
2981 }
2982 }
2983
2984 let (first, first_span) = match self.current_token() {
2985 Token::Ident(name, span, ..) => (intern(&name), span),
2986 token => {
2987 return Err(ParserErr::new(
2988 *token.span(),
2989 format!("expected library path segment got {}", token),
2990 ));
2991 }
2992 };
2993 segments.push(first);
2994 let mut end = first_span.end;
2995 self.next_token();
2996
2997 loop {
2998 if !matches!(self.current_token(), Token::Dot(..) | Token::Div(..)) {
2999 break;
3000 }
3001 self.next_token();
3002 let (seg, seg_span) = match self.current_token() {
3003 Token::Ident(name, span, ..) => (intern(&name), span),
3004 token => {
3005 return Err(ParserErr::new(
3006 *token.span(),
3007 format!("expected library path segment got {}", token),
3008 ));
3009 }
3010 };
3011 segments.push(seg);
3012 end = seg_span.end;
3013 self.next_token();
3014 }
3015
3016 Ok((segments, end))
3017 }
3018
3019 fn parse_type_decl(&mut self, is_pub: bool) -> Result<TypeDecl, ParserErr> {
3020 let span_begin = match self.current_token() {
3021 Token::Type(span, ..) => {
3022 self.next_token();
3023 span.begin
3024 }
3025 token => {
3026 return Err(ParserErr::new(
3027 *token.span(),
3028 format!("expected `type` got {}", token),
3029 ));
3030 }
3031 };
3032
3033 let (name, _name_span) = match self.current_token() {
3034 Token::Ident(name, span, ..) => {
3035 let name = intern(&name);
3036 self.next_token();
3037 (name, span)
3038 }
3039 token => {
3040 return Err(ParserErr::new(
3041 *token.span(),
3042 format!("expected type name got {}", token),
3043 ));
3044 }
3045 };
3046
3047 let mut params = Vec::new();
3048 while let Token::Ident(_param, ..) = self.current_token() {
3049 let name = match self.current_token() {
3050 Token::Ident(param, ..) => intern(¶m),
3051 _ => unreachable!(),
3052 };
3053 self.next_token();
3054 params.push(name);
3055 }
3056
3057 match self.current_token() {
3058 Token::Assign(..) => self.next_token(),
3059 token => {
3060 return Err(ParserErr::new(
3061 *token.span(),
3062 format!("expected `=` got {}", token),
3063 ));
3064 }
3065 }
3066
3067 let (first, first_span) = self.parse_type_variant()?;
3068 let mut variants = vec![first];
3069 let mut span_end = first_span.end;
3070 while let Token::Pipe(..) = self.current_token() {
3071 self.next_token();
3072 let (variant, vspan) = self.parse_type_variant()?;
3073 span_end = vspan.end;
3074 variants.push(variant);
3075 }
3076
3077 Ok(TypeDecl {
3078 span: Span::from_begin_end(span_begin, span_end),
3079 is_pub,
3080 name,
3081 params,
3082 variants,
3083 })
3084 }
3085
3086 fn parse_type_variant(&mut self) -> Result<(TypeVariant, Span), ParserErr> {
3087 let (name, name_span) = match self.current_token() {
3088 Token::Ident(name, span, ..) => {
3089 let name = intern(&name);
3090 self.next_token();
3091 (name, span)
3092 }
3093 token => {
3094 return Err(ParserErr::new(
3095 *token.span(),
3096 format!("expected constructor name got {}", token),
3097 ));
3098 }
3099 };
3100
3101 let mut args = Vec::new();
3102 let mut span_end = name_span.end;
3103 while let Token::Ident(..) | Token::ParenL(..) | Token::BraceL(..) = self.current_token() {
3104 let arg = self.parse_type_atom()?;
3105 span_end = arg.span().end;
3106 args.push(arg);
3107 }
3108
3109 Ok((
3110 TypeVariant { name, args },
3111 Span::from_begin_end(name_span.begin, span_end),
3112 ))
3113 }
3114
3115 fn parse_type_expr(&mut self) -> Result<TypeExpr, ParserErr> {
3116 self.parse_type_fun()
3117 }
3118
3119 fn parse_type_fun(&mut self) -> Result<TypeExpr, ParserErr> {
3120 let span = *self.current_token().span();
3121 self.with_nesting(span, |this| {
3122 let lhs = this.parse_type_app()?;
3123 match this.current_token() {
3124 Token::ArrowR(..) => {
3125 this.next_token();
3126 let rhs = this.parse_type_fun()?;
3127 let span = Span::from_begin_end(lhs.span().begin, rhs.span().end);
3128 Ok(TypeExpr::Fun(span, Box::new(lhs), Box::new(rhs)))
3129 }
3130 _ => Ok(lhs),
3131 }
3132 })
3133 }
3134
3135 fn parse_type_app(&mut self) -> Result<TypeExpr, ParserErr> {
3136 let mut lhs = self.parse_type_atom()?;
3137 while let Token::Ident(..) | Token::ParenL(..) | Token::BraceL(..) = self.current_token() {
3138 let rhs = self.parse_type_atom()?;
3139 let span = Span::from_begin_end(lhs.span().begin, rhs.span().end);
3140 lhs = TypeExpr::App(span, Box::new(lhs), Box::new(rhs));
3141 }
3142 Ok(lhs)
3143 }
3144
3145 fn parse_type_atom(&mut self) -> Result<TypeExpr, ParserErr> {
3146 match self.current_token() {
3147 Token::Ident(..) => {
3148 let (name, span) = self.parse_name_ref_with_span("expected type identifier")?;
3149 Ok(TypeExpr::Name(span, name))
3150 }
3151 Token::ParenL(..) => self.parse_type_paren(),
3152 Token::BraceL(..) => self.parse_type_record(),
3153 token => Err(ParserErr::new(
3154 *token.span(),
3155 format!("unexpected {} in type", token),
3156 )),
3157 }
3158 }
3159
3160 fn parse_type_paren(&mut self) -> Result<TypeExpr, ParserErr> {
3161 let span_begin = match self.current_token() {
3162 Token::ParenL(span, ..) => {
3163 self.next_token();
3164 span.begin
3165 }
3166 token => {
3167 return Err(ParserErr::new(
3168 *token.span(),
3169 format!("expected `(` got {}", token),
3170 ));
3171 }
3172 };
3173
3174 self.with_nesting(Span::from_begin_end(span_begin, span_begin), |this| {
3175 if let Token::ParenR(span, ..) = this.current_token() {
3177 this.next_token();
3178 return Ok(TypeExpr::Tuple(
3179 Span::from_begin_end(span_begin, span.end),
3180 Vec::new(),
3181 ));
3182 }
3183
3184 let first = this.parse_type_expr()?;
3185 let mut elems = Vec::new();
3186 let span_end = match this.current_token() {
3187 Token::Comma(..) => {
3188 this.next_token();
3189 elems.push(first);
3190 loop {
3191 elems.push(this.parse_type_expr()?);
3192 match this.current_token() {
3193 Token::Comma(..) => {
3194 this.next_token();
3195 continue;
3196 }
3197 Token::ParenR(span, ..) => {
3198 this.next_token();
3199 break span.end;
3200 }
3201 token => {
3202 return Err(ParserErr::new(
3203 *token.span(),
3204 format!("expected `)` got {}", token),
3205 ));
3206 }
3207 }
3208 }
3209 }
3210 Token::ParenR(_span, ..) => {
3211 this.next_token();
3212 return Ok(first);
3213 }
3214 token => {
3215 return Err(ParserErr::new(
3216 *token.span(),
3217 format!("expected `)` or `,` got {}", token),
3218 ));
3219 }
3220 };
3221
3222 Ok(TypeExpr::Tuple(
3223 Span::from_begin_end(span_begin, span_end),
3224 elems,
3225 ))
3226 })
3227 }
3228
3229 fn parse_type_record(&mut self) -> Result<TypeExpr, ParserErr> {
3230 let span_begin = match self.current_token() {
3231 Token::BraceL(span, ..) => {
3232 self.next_token();
3233 span.begin
3234 }
3235 token => {
3236 return Err(ParserErr::new(
3237 *token.span(),
3238 format!("expected `{{` got {}", token),
3239 ));
3240 }
3241 };
3242
3243 self.with_nesting(Span::from_begin_end(span_begin, span_begin), |this| {
3244 let mut fields = Vec::new();
3245 if let Token::BraceR(span, ..) = this.current_token() {
3246 this.next_token();
3247 return Ok(TypeExpr::Record(
3248 Span::from_begin_end(span_begin, span.end),
3249 fields,
3250 ));
3251 }
3252
3253 let span_end = loop {
3254 let (name, _span) = match this.current_token() {
3255 Token::Ident(name, span, ..) => {
3256 let name = intern(&name);
3257 this.next_token();
3258 (name, span)
3259 }
3260 token => {
3261 return Err(ParserErr::new(
3262 *token.span(),
3263 format!("expected field name got {}", token),
3264 ));
3265 }
3266 };
3267
3268 match this.current_token() {
3269 Token::Colon(..) => this.next_token(),
3270 token => {
3271 return Err(ParserErr::new(
3272 *token.span(),
3273 format!("expected `:` got {}", token),
3274 ));
3275 }
3276 }
3277
3278 let ty = this.parse_type_expr()?;
3279 fields.push((name, ty));
3280
3281 match this.current_token() {
3282 Token::Comma(..) => {
3283 this.next_token();
3284 }
3285 Token::BraceR(span, ..) => {
3286 this.next_token();
3287 break span.end;
3288 }
3289 token => {
3290 return Err(ParserErr::new(
3291 *token.span(),
3292 format!("expected `}}` got {}", token),
3293 ));
3294 }
3295 }
3296 };
3297
3298 Ok(TypeExpr::Record(
3299 Span::from_begin_end(span_begin, span_end),
3300 fields,
3301 ))
3302 })
3303 }
3304
3305 fn parse_pattern(&mut self) -> Result<Pattern, ParserErr> {
3306 self.parse_pattern_cons()
3307 }
3308
3309 fn parse_pattern_cons(&mut self) -> Result<Pattern, ParserErr> {
3310 let span = *self.current_token().span();
3311 self.with_nesting(span, |this| {
3312 let mut lhs = this.parse_pattern_app()?;
3313 while let Token::ColonColon(..) = this.current_token() {
3314 this.next_token();
3315 let rhs = this.parse_pattern_cons()?;
3316 let span = Span::from_begin_end(lhs.span().begin, rhs.span().end);
3317 lhs = Pattern::Cons(span, Box::new(lhs), Box::new(rhs));
3318 }
3319 Ok(lhs)
3320 })
3321 }
3322
3323 fn parse_pattern_app(&mut self) -> Result<Pattern, ParserErr> {
3324 let mut head = self.parse_pattern_atom()?;
3325 if let Pattern::Var(var) = &head
3326 && matches!(self.current_token(), Token::Dot(..))
3327 {
3328 let mut segments = vec![var.name.clone()];
3329 let mut end = var.span.end;
3330 while matches!(self.current_token(), Token::Dot(..)) {
3331 self.next_token();
3332 match self.current_token() {
3333 Token::Ident(name, seg_span, ..) => {
3334 segments.push(intern(&name));
3335 end = seg_span.end;
3336 self.next_token();
3337 }
3338 token => {
3339 return Err(ParserErr::new(
3340 *token.span(),
3341 "expected identifier after `.` in constructor pattern",
3342 ));
3343 }
3344 }
3345 }
3346 head = Pattern::Named(
3347 Span::from_begin_end(var.span.begin, end),
3348 NameRef::from_segments(segments),
3349 vec![],
3350 );
3351 }
3352
3353 let mut args = Vec::new();
3354 while let Token::Ident(..) | Token::BracketL(..) | Token::BraceL(..) | Token::ParenL(..) =
3355 self.current_token()
3356 {
3357 let arg = self.parse_pattern_atom()?;
3358 args.push(arg);
3359 }
3360
3361 if args.is_empty() {
3362 if let Pattern::Var(var) = &head {
3363 let is_constructor = var
3364 .name
3365 .chars()
3366 .next()
3367 .map(|c| c.is_uppercase())
3368 .unwrap_or(false);
3369 if is_constructor {
3370 return Ok(Pattern::Named(
3371 var.span,
3372 NameRef::Unqualified(var.name.clone()),
3373 vec![],
3374 ));
3375 }
3376 }
3377 return Ok(head);
3378 }
3379
3380 match head {
3382 Pattern::Var(var) => {
3383 let begin = var.span.begin;
3384 let end = args.last().map(|p| p.span().end).unwrap_or(begin);
3385 Ok(Pattern::Named(
3386 Span::from_begin_end(begin, end),
3387 NameRef::Unqualified(var.name),
3388 args,
3389 ))
3390 }
3391 Pattern::Named(span, name, mut existing_args) => {
3392 existing_args.extend(args);
3393 let end = existing_args
3394 .last()
3395 .map(|p| p.span().end)
3396 .unwrap_or(span.end);
3397 Ok(Pattern::Named(
3398 Span::from_begin_end(span.begin, end),
3399 name,
3400 existing_args,
3401 ))
3402 }
3403 _ => {
3404 let span = args
3405 .first()
3406 .map(|p| *p.span())
3407 .unwrap_or_else(|| *self.current_token().span());
3408 Err(ParserErr::new(
3409 span,
3410 "constructor patterns must start with an identifier",
3411 ))
3412 }
3413 }
3414 }
3415
3416 fn parse_name_ref_with_span(
3417 &mut self,
3418 expected_message: &str,
3419 ) -> Result<(NameRef, Span), ParserErr> {
3420 let mut segments: Vec<Symbol> = Vec::new();
3421 let start = self.current_token().span().begin;
3422 let mut end = match self.current_token() {
3423 Token::Ident(name, span, ..) => {
3424 segments.push(intern(&name));
3425 self.next_token();
3426 span.end
3427 }
3428 token => return Err(ParserErr::new(*token.span(), expected_message)),
3429 };
3430
3431 while matches!(self.current_token(), Token::Dot(..)) {
3432 self.next_token();
3433 match self.current_token() {
3434 Token::Ident(name, span, ..) => {
3435 segments.push(intern(&name));
3436 end = span.end;
3437 self.next_token();
3438 }
3439 token => {
3440 return Err(ParserErr::new(
3441 *token.span(),
3442 "expected identifier after `.`",
3443 ));
3444 }
3445 }
3446 }
3447
3448 Ok((
3449 NameRef::from_segments(segments),
3450 Span::from_begin_end(start, end),
3451 ))
3452 }
3453
3454 fn parse_pattern_atom(&mut self) -> Result<Pattern, ParserErr> {
3455 match self.current_token() {
3456 Token::Ident(name, span, ..) if name == "_" => {
3457 self.next_token();
3458 Ok(Pattern::Wildcard(span))
3459 }
3460 Token::Ident(name, span, ..) => {
3461 self.next_token();
3462 Ok(Pattern::Var(Var::with_span(span, name)))
3463 }
3464 Token::BracketL(..) => self.parse_list_pattern(),
3465 Token::BraceL(..) => self.parse_dict_pattern(),
3466 Token::ParenL(..) => self.parse_paren_pattern(),
3467 token => Err(ParserErr::new(
3468 *token.span(),
3469 format!("unexpected {} in pattern", token),
3470 )),
3471 }
3472 }
3473
3474 fn parse_list_pattern(&mut self) -> Result<Pattern, ParserErr> {
3475 let span_begin = match self.current_token() {
3476 Token::BracketL(span, ..) => {
3477 self.next_token();
3478 span.begin
3479 }
3480 token => {
3481 return Err(ParserErr::new(
3482 *token.span(),
3483 format!("expected `[` got {}", token),
3484 ));
3485 }
3486 };
3487
3488 self.with_nesting(Span::from_begin_end(span_begin, span_begin), |this| {
3489 if let Token::BracketR(span, ..) = this.current_token() {
3490 this.next_token();
3491 return Ok(Pattern::List(
3492 Span::from_begin_end(span_begin, span.end),
3493 Vec::new(),
3494 ));
3495 }
3496
3497 let mut patterns = Vec::new();
3498 let span_end = loop {
3499 patterns.push(this.parse_pattern()?);
3500
3501 match this.current_token() {
3502 Token::Comma(..) => {
3503 this.next_token();
3504 }
3505 Token::BracketR(span, ..) => {
3506 this.next_token();
3507 break span.end;
3508 }
3509 token => {
3510 return Err(ParserErr::new(
3511 *token.span(),
3512 format!("expected `,` or `]` got {}", token),
3513 ));
3514 }
3515 }
3516 };
3517
3518 Ok(Pattern::List(
3519 Span::from_begin_end(span_begin, span_end),
3520 patterns,
3521 ))
3522 })
3523 }
3524
3525 fn parse_dict_pattern(&mut self) -> Result<Pattern, ParserErr> {
3526 let span_begin = match self.current_token() {
3527 Token::BraceL(span, ..) => {
3528 self.next_token();
3529 span.begin
3530 }
3531 token => {
3532 return Err(ParserErr::new(
3533 *token.span(),
3534 format!("expected `{{` got {}", token),
3535 ));
3536 }
3537 };
3538
3539 self.with_nesting(Span::from_begin_end(span_begin, span_begin), |this| {
3540 if let Token::BraceR(span, ..) = this.current_token() {
3541 this.next_token();
3542 return Ok(Pattern::Dict(
3543 Span::from_begin_end(span_begin, span.end),
3544 Vec::new(),
3545 ));
3546 }
3547
3548 let mut fields = Vec::new();
3549 let span_end = loop {
3550 match this.current_token() {
3551 Token::Ident(name, key_span, ..) => {
3552 let key_name = name;
3553 let key = intern(&key_name);
3554 this.next_token();
3555
3556 let pat = if matches!(this.current_token(), Token::Colon(..)) {
3557 this.next_token();
3558 this.parse_pattern()?
3559 } else {
3560 Pattern::Var(Var::with_span(key_span, key_name))
3561 };
3562 fields.push((key, pat));
3563
3564 match this.current_token() {
3565 Token::Comma(..) => {
3566 this.next_token();
3567 }
3568 Token::BraceR(span, ..) => {
3569 this.next_token();
3570 break span.end;
3571 }
3572 token => {
3573 return Err(ParserErr::new(
3574 *token.span(),
3575 format!("expected `,` or `}}` got {}", token),
3576 ));
3577 }
3578 }
3579 }
3580 token => {
3581 return Err(ParserErr::new(
3582 *token.span(),
3583 format!("expected identifier in dict pattern got {}", token),
3584 ));
3585 }
3586 }
3587 };
3588
3589 Ok(Pattern::Dict(
3590 Span::from_begin_end(span_begin, span_end),
3591 fields,
3592 ))
3593 })
3594 }
3595
3596 fn parse_paren_pattern(&mut self) -> Result<Pattern, ParserErr> {
3597 let span_begin = match self.current_token() {
3598 Token::ParenL(span, ..) => {
3599 self.next_token();
3600 span.begin
3601 }
3602 token => {
3603 return Err(ParserErr::new(
3604 *token.span(),
3605 format!("expected `(` got {}", token),
3606 ));
3607 }
3608 };
3609
3610 self.with_nesting(Span::from_begin_end(span_begin, span_begin), |this| {
3611 if let Token::ParenR(span, ..) = this.current_token() {
3613 this.next_token();
3614 return Ok(Pattern::Tuple(
3615 Span::from_begin_end(span_begin, span.end),
3616 Vec::new(),
3617 ));
3618 }
3619
3620 let first = this.parse_pattern()?;
3621 let mut elems = Vec::new();
3622 let span_end = match this.current_token() {
3623 Token::Comma(..) => {
3624 this.next_token();
3625 elems.push(first);
3626 loop {
3627 elems.push(this.parse_pattern()?);
3628 match this.current_token() {
3629 Token::Comma(..) => {
3630 this.next_token();
3631 }
3632 Token::ParenR(span, ..) => {
3633 this.next_token();
3634 break span.end;
3635 }
3636 token => {
3637 return Err(ParserErr::new(
3638 *token.span(),
3639 format!("expected `)` got {}", token),
3640 ));
3641 }
3642 }
3643 }
3644 }
3645 Token::ParenR(span, ..) => {
3646 this.next_token();
3647 return Ok(first.with_span(Span::from_begin_end(span_begin, span.end)));
3648 }
3649 token => {
3650 return Err(ParserErr::new(
3651 *token.span(),
3652 format!("expected `)` or `,` got {}", token),
3653 ));
3654 }
3655 };
3656
3657 Ok(Pattern::Tuple(
3658 Span::from_begin_end(span_begin, span_end),
3659 elems,
3660 ))
3661 })
3662 }
3663
3664 fn parse_literal_bool_expr(&mut self) -> Result<Expr, ParserErr> {
3666 let token = self.current_token();
3667 self.next_token();
3668 match token {
3669 Token::Bool(val, span, ..) => Ok(Expr::Bool(span, val)),
3670 token => Err(ParserErr::new(
3671 *token.span(),
3672 format!("expected `bool` got {}", token),
3673 )),
3674 }
3675 }
3676
3677 fn parse_literal_float_expr(&mut self) -> Result<Expr, ParserErr> {
3679 let token = self.current_token();
3680 self.next_token();
3681 match token {
3682 Token::Float(val, span, ..) => Ok(Expr::Float(span, val)),
3683 token => Err(ParserErr::new(
3684 *token.span(),
3685 format!("expected `float` got {}", token),
3686 )),
3687 }
3688 }
3689
3690 fn parse_literal_int_expr(&mut self) -> Result<Expr, ParserErr> {
3692 let token = self.current_token();
3693 self.next_token();
3694 match token {
3695 Token::Int(val, span, ..) => Ok(Expr::Uint(span, val)),
3696 token => Err(ParserErr::new(
3697 *token.span(),
3698 format!("expected `int` got {}", token),
3699 )),
3700 }
3701 }
3702
3703 fn parse_literal_str_expr(&mut self) -> Result<Expr, ParserErr> {
3705 let token = self.current_token();
3706 self.next_token();
3707 match token {
3708 Token::String(val, span, ..) => Ok(Expr::String(span, val)),
3709 token => Err(ParserErr::new(
3710 *token.span(),
3711 format!("expected `str` got {}", token),
3712 )),
3713 }
3714 }
3715
3716 fn parse_ident_expr(&mut self) -> Result<Expr, ParserErr> {
3718 let token = self.current_token();
3719 self.next_token();
3720 match token {
3721 Token::Ident(name, span, ..) => Ok(Expr::Var(Var::with_span(span, name))),
3722 token => Err(ParserErr::new(
3723 *token.span(),
3724 format!("expected `ident` got {}", token),
3725 )),
3726 }
3727 }
3728
3729 fn parse_hole_expr(&mut self) -> Result<Expr, ParserErr> {
3730 let token = self.current_token();
3731 self.next_token();
3732 match token {
3733 Token::Question(span, ..) => Ok(Expr::Hole(span)),
3734 token => Err(ParserErr::new(
3735 *token.span(),
3736 format!("expected `?` got {}", token),
3737 )),
3738 }
3739 }
3740}
3741
3742fn find_layout_expr_end(
3743 tokens: &[Token],
3744 start_idx: usize,
3745 block_indent: Option<usize>,
3746 is_stmt_head: impl Fn(&Token, &Token) -> bool,
3747) -> usize {
3748 let mut depth = 0usize;
3752 let mut idx = start_idx;
3753 while idx < tokens.len() {
3754 match &tokens[idx] {
3755 Token::ParenL(..) | Token::BracketL(..) | Token::BraceL(..) => depth += 1,
3756 Token::ParenR(..) | Token::BracketR(..) | Token::BraceR(..) => {
3757 depth = depth.saturating_sub(1)
3758 }
3759 Token::WhitespaceNewline(nl_span, ..) if depth == 0 => {
3760 let mut j = idx + 1;
3761 while j < tokens.len() && matches!(tokens[j], Token::WhitespaceNewline(..)) {
3762 j += 1;
3763 }
3764 if j >= tokens.len() {
3765 return idx;
3766 }
3767 if let Some(indent) = block_indent {
3768 let next_span = tokens[j].span();
3769 if next_span.begin.column < indent {
3770 return idx;
3771 }
3772 if next_span.begin.column == indent {
3773 let mut k = j + 1;
3775 while k < tokens.len() && matches!(tokens[k], Token::WhitespaceNewline(..))
3776 {
3777 k += 1;
3778 }
3779 if k < tokens.len() && is_stmt_head(&tokens[j], &tokens[k]) {
3780 return idx;
3781 }
3782 }
3783 } else {
3784 let _ = nl_span;
3785 }
3786 }
3787 _ => {}
3788 }
3789 idx += 1;
3790 }
3791 tokens.len()
3792}
3793
3794fn find_layout_header_clause_end(
3795 tokens: &[Token],
3796 start_idx: usize,
3797 is_terminator: impl Fn(&Token) -> bool,
3798) -> usize {
3799 let mut depth = 0usize;
3808 let mut idx = start_idx;
3809 while idx < tokens.len() {
3810 match &tokens[idx] {
3811 Token::ParenL(..) | Token::BracketL(..) | Token::BraceL(..) => depth += 1,
3812 Token::ParenR(..) | Token::BracketR(..) | Token::BraceR(..) => {
3813 depth = depth.saturating_sub(1)
3814 }
3815 Token::WhitespaceNewline(..) if depth == 0 => return idx,
3816 token if depth == 0 && is_terminator(token) => return idx,
3817 _ => {}
3818 }
3819 idx += 1;
3820 }
3821 tokens.len()
3822}
3823
3824fn count_expr_nodes(expr: &Expr) -> u64 {
3825 match expr {
3826 Expr::Bool(..)
3827 | Expr::Uint(..)
3828 | Expr::Int(..)
3829 | Expr::Float(..)
3830 | Expr::String(..)
3831 | Expr::Uuid(..)
3832 | Expr::DateTime(..)
3833 | Expr::Hole(..)
3834 | Expr::Var(..) => 1,
3835 Expr::Tuple(_, xs) | Expr::List(_, xs) => {
3836 1 + xs.iter().map(|e| count_expr_nodes(e)).sum::<u64>()
3837 }
3838 Expr::Dict(_, kvs) => 1 + kvs.values().map(|e| count_expr_nodes(e)).sum::<u64>(),
3839 Expr::RecordUpdate(_, base, updates) => {
3840 1 + count_expr_nodes(base) + updates.values().map(|e| count_expr_nodes(e)).sum::<u64>()
3841 }
3842 Expr::App(_, f, x) => 1 + count_expr_nodes(f) + count_expr_nodes(x),
3843 Expr::Project(_, e, _) => 1 + count_expr_nodes(e),
3844 Expr::Lam(_, _, _, ann, constraints, body) => {
3845 let ann_nodes = ann.as_ref().map(count_type_expr_nodes).unwrap_or(0);
3846 let constraint_nodes = constraints
3847 .iter()
3848 .map(count_type_constraint_nodes)
3849 .sum::<u64>();
3850 1 + ann_nodes + constraint_nodes + count_expr_nodes(body)
3851 }
3852 Expr::Let(_, _, ann, def, body) => {
3853 let ann_nodes = ann.as_ref().map(count_type_expr_nodes).unwrap_or(0);
3854 1 + ann_nodes + count_expr_nodes(def) + count_expr_nodes(body)
3855 }
3856 Expr::LetRec(_, bindings, body) => {
3857 let binding_nodes = bindings
3858 .iter()
3859 .map(|(_, ann, def)| {
3860 ann.as_ref().map(count_type_expr_nodes).unwrap_or(0) + count_expr_nodes(def)
3861 })
3862 .sum::<u64>();
3863 1 + binding_nodes + count_expr_nodes(body)
3864 }
3865 Expr::Ite(_, a, b, c) => {
3866 1 + count_expr_nodes(a) + count_expr_nodes(b) + count_expr_nodes(c)
3867 }
3868 Expr::Match(_, scrutinee, arms) => {
3869 1 + count_expr_nodes(scrutinee)
3870 + arms
3871 .iter()
3872 .map(|(pat, e)| count_pattern_nodes(pat) + count_expr_nodes(e))
3873 .sum::<u64>()
3874 }
3875 Expr::Ann(_, e, ty) => 1 + count_expr_nodes(e) + count_type_expr_nodes(ty),
3876 }
3877}
3878
3879fn count_pattern_nodes(pat: &Pattern) -> u64 {
3880 match pat {
3881 Pattern::Wildcard(..) | Pattern::Var(..) => 1,
3882 Pattern::Named(_, _, ps) | Pattern::Tuple(_, ps) | Pattern::List(_, ps) => {
3883 1 + ps.iter().map(count_pattern_nodes).sum::<u64>()
3884 }
3885 Pattern::Cons(_, a, b) => 1 + count_pattern_nodes(a) + count_pattern_nodes(b),
3886 Pattern::Dict(_, fields) => {
3887 1 + fields
3888 .iter()
3889 .map(|(_, p)| count_pattern_nodes(p))
3890 .sum::<u64>()
3891 }
3892 }
3893}
3894
3895fn count_type_constraint_nodes(c: &TypeConstraint) -> u64 {
3896 1 + count_type_expr_nodes(&c.typ)
3897}
3898
3899fn count_type_expr_nodes(ty: &TypeExpr) -> u64 {
3900 match ty {
3901 TypeExpr::Name(..) => 1,
3902 TypeExpr::App(_, a, b) | TypeExpr::Fun(_, a, b) => {
3903 1 + count_type_expr_nodes(a) + count_type_expr_nodes(b)
3904 }
3905 TypeExpr::Tuple(_, elems) => 1 + elems.iter().map(count_type_expr_nodes).sum::<u64>(),
3906 TypeExpr::Record(_, fields) => {
3907 1 + fields
3908 .iter()
3909 .map(|(_, t)| count_type_expr_nodes(t))
3910 .sum::<u64>()
3911 }
3912 }
3913}