1use crate::ast::*;
2use crate::intern::{StringInterner, Symbol};
3use crate::span::Span;
4use crate::token::{Token, TokenKind};
5
6#[derive(Debug, Clone)]
7pub struct ParseError {
8 pub message: String,
9 pub span: Span,
10}
11
12pub struct Parser {
13 tokens: Vec<Token>,
14 pos: usize,
15 depth: u32,
16 interner: StringInterner,
17}
18
19impl Parser {
20 pub fn new(tokens: Vec<Token>) -> Self {
21 Self {
22 tokens,
23 pos: 0,
24 depth: 0,
25 interner: StringInterner::new(),
26 }
27 }
28
29 pub fn with_interner(tokens: Vec<Token>, interner: StringInterner) -> Self {
30 Self {
31 tokens,
32 pos: 0,
33 depth: 0,
34 interner,
35 }
36 }
37
38 fn peek(&self) -> &TokenKind {
41 &self.tokens[self.pos].kind
42 }
43
44 fn span(&self) -> Span {
45 self.tokens[self.pos].span
46 }
47
48 fn advance(&mut self) {
49 if self.pos + 1 < self.tokens.len() {
50 self.pos += 1;
51 }
52 }
53
54 fn eat(&mut self, kind: &TokenKind) -> Option<Span> {
55 if std::mem::discriminant(self.peek()) == std::mem::discriminant(kind) {
56 let span = self.span();
57 self.advance();
58 Some(span)
59 } else {
60 None
61 }
62 }
63
64 fn expect(&mut self, kind: &TokenKind, desc: &str) -> Result<Span, ParseError> {
65 self.eat(kind)
66 .ok_or_else(|| self.err(&format!("expected {desc}")))
67 }
68
69 fn take_symbol(&mut self) -> Symbol {
71 let s = match &mut self.tokens[self.pos].kind {
72 TokenKind::Ident(s) | TokenKind::UpperIdent(s) | TokenKind::TyVar(s) => {
73 std::mem::take(s)
74 }
75 _ => String::new(),
76 };
77 self.advance();
78 self.interner.intern(&s)
79 }
80
81 fn take_string_lit(&mut self) -> String {
83 let s = match &mut self.tokens[self.pos].kind {
84 TokenKind::StringLit(s) => std::mem::take(s),
85 _ => String::new(),
86 };
87 self.advance();
88 s
89 }
90
91 fn expect_ident(&mut self) -> Result<(Symbol, Span), ParseError> {
92 if matches!(self.peek(), TokenKind::Ident(_)) {
93 let span = self.span();
94 Ok((self.take_symbol(), span))
95 } else {
96 Err(self.err("expected identifier"))
97 }
98 }
99
100 fn expect_ident_or_wildcard(&mut self) -> Result<(Symbol, Span), ParseError> {
101 if matches!(self.peek(), TokenKind::Ident(_)) {
102 let span = self.span();
103 Ok((self.take_symbol(), span))
104 } else if matches!(self.peek(), TokenKind::Underscore) {
105 let span = self.span();
106 self.advance();
107 Ok((self.interner.intern("_"), span))
108 } else {
109 Err(self.err("expected identifier or _"))
110 }
111 }
112
113 fn expect_upper_ident(&mut self) -> Result<(Symbol, Span), ParseError> {
114 if matches!(self.peek(), TokenKind::UpperIdent(_)) {
115 let span = self.span();
116 Ok((self.take_symbol(), span))
117 } else {
118 Err(self.err("expected constructor name"))
119 }
120 }
121
122 fn expect_name(&mut self) -> Result<(Symbol, Span), ParseError> {
123 if matches!(self.peek(), TokenKind::Ident(_) | TokenKind::UpperIdent(_)) {
124 let span = self.span();
125 Ok((self.take_symbol(), span))
126 } else {
127 Err(self.err("expected name"))
128 }
129 }
130
131 fn expect_tyvar(&mut self) -> Result<Symbol, ParseError> {
132 if matches!(self.peek(), TokenKind::TyVar(_)) {
133 Ok(self.take_symbol())
134 } else {
135 Err(self.err("expected type variable"))
136 }
137 }
138
139 fn err(&self, message: &str) -> ParseError {
140 ParseError {
141 message: message.to_string(),
142 span: self.span(),
143 }
144 }
145
146 fn guard_depth(&mut self) -> Result<(), ParseError> {
147 self.depth += 1;
148 if self.depth > 256 {
149 Err(self.err("expression nesting limit exceeded"))
150 } else {
151 Ok(())
152 }
153 }
154
155 fn unguard_depth(&mut self) {
156 self.depth -= 1;
157 }
158
159 fn can_start_app_arg(&self) -> bool {
160 matches!(
161 self.peek(),
162 TokenKind::IntLit(_)
163 | TokenKind::FloatLit(_)
164 | TokenKind::StringLit(_)
165 | TokenKind::CharLit(_)
166 | TokenKind::True
167 | TokenKind::False
168 | TokenKind::Ident(_)
169 | TokenKind::UpperIdent(_)
170 | TokenKind::Tilde
171 | TokenKind::Not
172 | TokenKind::LParen
173 | TokenKind::LBracket
174 )
175 }
176
177 fn can_start_atom_pat(&self) -> bool {
178 matches!(
179 self.peek(),
180 TokenKind::Underscore
181 | TokenKind::IntLit(_)
182 | TokenKind::FloatLit(_)
183 | TokenKind::StringLit(_)
184 | TokenKind::CharLit(_)
185 | TokenKind::True
186 | TokenKind::False
187 | TokenKind::Ident(_)
188 | TokenKind::UpperIdent(_)
189 | TokenKind::LParen
190 | TokenKind::LBracket
191 | TokenKind::Tilde
192 )
193 }
194
195 pub fn parse_program(&mut self) -> Result<Program, ParseError> {
198 let mut decls = Vec::new();
199 while !matches!(self.peek(), TokenKind::Eof) {
200 decls.push(self.parse_decl()?);
201 }
202 Ok(Program {
203 decls,
204 interner: std::mem::take(&mut self.interner),
205 })
206 }
207
208 fn parse_decl(&mut self) -> Result<Decl, ParseError> {
211 match self.peek() {
212 TokenKind::Val => self.parse_val_decl(),
213 TokenKind::Fun => self.parse_fun_decl(),
214 TokenKind::Datatype => self.parse_datatype_decl(),
215 TokenKind::Type => self.parse_type_alias_decl(),
216 TokenKind::Local => self.parse_local_decl(),
217 TokenKind::Use => self.parse_use_decl(),
218 TokenKind::Effect => self.parse_effect_decl(),
219 _ => {
220 Err(self
221 .err("expected declaration (val, fun, datatype, type, local, use, or effect)"))
222 }
223 }
224 }
225
226 fn parse_val_decl(&mut self) -> Result<Decl, ParseError> {
227 let start = self.span();
228 self.advance(); if self.eat(&TokenKind::Rec).is_some() {
231 let (name, _) = self.expect_ident()?;
232 self.expect(&TokenKind::Eq, "=")?;
233 if !matches!(self.peek(), TokenKind::Fn) {
234 return Err(self.err("val rec requires fn on the right-hand side"));
235 }
236 let body = self.parse_expr()?;
237 let span = start.merge(body.span);
238 return Ok(Decl {
239 kind: DeclKind::ValRec(name, body),
240 span,
241 });
242 }
243
244 let pat = self.parse_pat()?;
245 self.expect(&TokenKind::Eq, "=")?;
246 let body = self.parse_expr()?;
247 let span = start.merge(body.span);
248 Ok(Decl {
249 kind: DeclKind::Val(pat, body),
250 span,
251 })
252 }
253
254 fn parse_fun_decl(&mut self) -> Result<Decl, ParseError> {
255 let start = self.span();
256 self.advance(); let mut bindings = Vec::new();
259 loop {
260 bindings.push(self.parse_fun_binding()?);
261 if self.eat(&TokenKind::And).is_none() {
262 break;
263 }
264 }
265 let span = start.merge(bindings.last().unwrap().span);
266 Ok(Decl {
267 kind: DeclKind::Fun(bindings),
268 span,
269 })
270 }
271
272 fn parse_fun_binding(&mut self) -> Result<FunBinding, ParseError> {
273 let (name, name_span) = self.expect_ident()?;
274 let mut clauses = Vec::new();
275
276 loop {
277 let clause_start = self.span();
278 let mut pats = Vec::new();
279 while self.can_start_atom_pat() {
280 pats.push(self.parse_atom_pat()?);
281 }
282 if pats.is_empty() {
283 return Err(self.err("expected at least one parameter pattern"));
284 }
285 self.expect(&TokenKind::Eq, "=")?;
286 let body = self.parse_expr()?;
287 let clause_span = clause_start.merge(body.span);
288 clauses.push(FunClause {
289 pats,
290 body,
291 span: clause_span,
292 });
293
294 if matches!(self.peek(), TokenKind::Bar) {
296 self.advance(); let (next_name, _) = self.expect_ident()?;
299 if next_name != name {
300 return Err(self.err(&format!(
301 "clausal function name mismatch: expected '{}', found '{}'",
302 self.interner.resolve(name),
303 self.interner.resolve(next_name),
304 )));
305 }
306 } else {
307 break;
308 }
309 }
310
311 let span = name_span.merge(clauses.last().unwrap().span);
312 Ok(FunBinding {
313 name,
314 clauses,
315 span,
316 })
317 }
318
319 fn parse_datatype_decl(&mut self) -> Result<Decl, ParseError> {
320 let start = self.span();
321 self.advance(); let tyvars = self.parse_tyvar_params()?;
324 let (name, _) = self.expect_name()?;
325 self.expect(&TokenKind::Eq, "=")?;
326
327 self.eat(&TokenKind::Bar); let mut constructors = Vec::new();
329 loop {
330 let con_start = self.span();
331 let (con_name, _) = self.expect_upper_ident()?;
332 let payload = if self.eat(&TokenKind::Of).is_some() {
333 Some(self.parse_type_expr()?)
334 } else {
335 None
336 };
337 let con_span = if let Some(ref ty) = payload {
338 con_start.merge(ty.span)
339 } else {
340 con_start
341 };
342 constructors.push(ConDecl {
343 name: con_name,
344 payload,
345 span: con_span,
346 });
347 if self.eat(&TokenKind::Bar).is_none() {
348 break;
349 }
350 }
351
352 let span = start.merge(constructors.last().unwrap().span);
353 Ok(Decl {
354 kind: DeclKind::Datatype(DatatypeDecl {
355 tyvars,
356 name,
357 constructors,
358 span,
359 }),
360 span,
361 })
362 }
363
364 fn parse_type_alias_decl(&mut self) -> Result<Decl, ParseError> {
365 let start = self.span();
366 self.advance(); let tyvars = self.parse_tyvar_params()?;
368 let (name, _) = self.expect_name()?;
369 self.expect(&TokenKind::Eq, "=")?;
370 let ty = self.parse_type_expr()?;
371 let span = start.merge(ty.span);
372 Ok(Decl {
373 kind: DeclKind::TypeAlias(TypeAliasDecl {
374 tyvars,
375 name,
376 ty,
377 span,
378 }),
379 span,
380 })
381 }
382
383 fn parse_local_decl(&mut self) -> Result<Decl, ParseError> {
384 let start = self.span();
385 self.advance(); let mut locals = Vec::new();
387 while !matches!(self.peek(), TokenKind::In | TokenKind::Eof) {
388 locals.push(self.parse_decl()?);
389 }
390 self.expect(&TokenKind::In, "in")?;
391 let mut body = Vec::new();
392 while !matches!(self.peek(), TokenKind::End | TokenKind::Eof) {
393 body.push(self.parse_decl()?);
394 }
395 let end_span = self.expect(&TokenKind::End, "end")?;
396 let span = start.merge(end_span);
397 Ok(Decl {
398 kind: DeclKind::Local(locals, body),
399 span,
400 })
401 }
402
403 fn parse_use_decl(&mut self) -> Result<Decl, ParseError> {
404 let start = self.span();
405 self.advance(); if matches!(self.peek(), TokenKind::StringLit(_)) {
407 let end = self.span();
408 let path = self.take_string_lit();
409 let span = start.merge(end);
410 Ok(Decl {
411 kind: DeclKind::Use(path),
412 span,
413 })
414 } else {
415 Err(self.err("expected string literal after 'use'"))
416 }
417 }
418
419 fn parse_effect_decl(&mut self) -> Result<Decl, ParseError> {
420 let start = self.span();
421 self.advance(); let (name, end) = self.expect_upper_ident()?;
423 let payload = if self.eat(&TokenKind::Of).is_some() {
424 Some(self.parse_type_expr()?)
425 } else {
426 None
427 };
428 let span = start.merge(payload.as_ref().map_or(end, |t| t.span));
429 Ok(Decl {
430 kind: DeclKind::Effect(name, payload),
431 span,
432 })
433 }
434
435 fn parse_tyvar_params(&mut self) -> Result<Vec<Symbol>, ParseError> {
436 if matches!(self.peek(), TokenKind::TyVar(_)) {
437 return Ok(vec![self.take_symbol()]);
438 }
439 if self.eat(&TokenKind::LParen).is_none() {
440 return Ok(vec![]);
441 }
442 let mut vars = vec![self.expect_tyvar()?];
443 while self.eat(&TokenKind::Comma).is_some() {
444 vars.push(self.expect_tyvar()?);
445 }
446 self.expect(&TokenKind::RParen, ")")?;
447 Ok(vars)
448 }
449
450 fn parse_expr(&mut self) -> Result<Expr, ParseError> {
453 self.guard_depth()?;
454 let result = self.parse_expr_inner();
455 self.unguard_depth();
456 result
457 }
458
459 fn parse_expr_inner(&mut self) -> Result<Expr, ParseError> {
460 let expr = self.parse_orelse()?;
461 if self.eat(&TokenKind::Colon).is_some() {
462 let ty = self.parse_type_expr()?;
463 let span = expr.span.merge(ty.span);
464 Ok(Expr {
465 kind: ExprKind::Ann(Box::new(expr), ty),
466 span,
467 })
468 } else {
469 Ok(expr)
470 }
471 }
472
473 fn parse_orelse(&mut self) -> Result<Expr, ParseError> {
474 let lhs = self.parse_andalso()?;
475 if self.eat(&TokenKind::Orelse).is_some() {
476 let rhs = self.parse_orelse()?; let span = lhs.span.merge(rhs.span);
478 Ok(Expr {
479 kind: ExprKind::BinOp(BinOp::Orelse, Box::new(lhs), Box::new(rhs)),
480 span,
481 })
482 } else {
483 Ok(lhs)
484 }
485 }
486
487 fn parse_andalso(&mut self) -> Result<Expr, ParseError> {
488 let lhs = self.parse_comp()?;
489 if self.eat(&TokenKind::Andalso).is_some() {
490 let rhs = self.parse_andalso()?; let span = lhs.span.merge(rhs.span);
492 Ok(Expr {
493 kind: ExprKind::BinOp(BinOp::Andalso, Box::new(lhs), Box::new(rhs)),
494 span,
495 })
496 } else {
497 Ok(lhs)
498 }
499 }
500
501 fn parse_comp(&mut self) -> Result<Expr, ParseError> {
502 let lhs = self.parse_cons()?;
503 let op = match self.peek() {
504 TokenKind::Eq => Some(BinOp::Eq),
505 TokenKind::Ne => Some(BinOp::Ne),
506 TokenKind::Lt => Some(BinOp::LtInt),
507 TokenKind::Gt => Some(BinOp::GtInt),
508 TokenKind::Le => Some(BinOp::LeInt),
509 TokenKind::Ge => Some(BinOp::GeInt),
510 TokenKind::LtDot => Some(BinOp::LtFloat),
511 TokenKind::GtDot => Some(BinOp::GtFloat),
512 TokenKind::LeDot => Some(BinOp::LeFloat),
513 TokenKind::GeDot => Some(BinOp::GeFloat),
514 _ => None,
515 };
516 if let Some(op) = op {
517 self.advance();
518 let rhs = self.parse_cons()?;
519 let span = lhs.span.merge(rhs.span);
520 Ok(Expr {
521 kind: ExprKind::BinOp(op, Box::new(lhs), Box::new(rhs)),
522 span,
523 })
524 } else {
525 Ok(lhs)
526 }
527 }
528
529 fn parse_cons(&mut self) -> Result<Expr, ParseError> {
530 let lhs = self.parse_add()?;
531 if self.eat(&TokenKind::ColonColon).is_some() {
532 let rhs = self.parse_cons()?; let span = lhs.span.merge(rhs.span);
534 Ok(Expr {
535 kind: ExprKind::Cons(Box::new(lhs), Box::new(rhs)),
536 span,
537 })
538 } else {
539 Ok(lhs)
540 }
541 }
542
543 fn parse_add(&mut self) -> Result<Expr, ParseError> {
544 let mut lhs = self.parse_mul()?;
545 loop {
546 let op = match self.peek() {
547 TokenKind::Plus => Some(BinOp::AddInt),
548 TokenKind::Minus => Some(BinOp::SubInt),
549 TokenKind::PlusDot => Some(BinOp::AddFloat),
550 TokenKind::MinusDot => Some(BinOp::SubFloat),
551 TokenKind::Caret => Some(BinOp::ConcatStr),
552 _ => None,
553 };
554 if let Some(op) = op {
555 self.advance();
556 let rhs = self.parse_mul()?;
557 let span = lhs.span.merge(rhs.span);
558 lhs = Expr {
559 kind: ExprKind::BinOp(op, Box::new(lhs), Box::new(rhs)),
560 span,
561 };
562 } else {
563 break;
564 }
565 }
566 Ok(lhs)
567 }
568
569 fn parse_mul(&mut self) -> Result<Expr, ParseError> {
570 let mut lhs = self.parse_unary()?;
571 loop {
572 let op = match self.peek() {
573 TokenKind::Star => Some(BinOp::MulInt),
574 TokenKind::Slash => Some(BinOp::DivInt),
575 TokenKind::Mod => Some(BinOp::ModInt),
576 TokenKind::StarDot => Some(BinOp::MulFloat),
577 TokenKind::SlashDot => Some(BinOp::DivFloat),
578 _ => None,
579 };
580 if let Some(op) = op {
581 self.advance();
582 let rhs = self.parse_unary()?;
583 let span = lhs.span.merge(rhs.span);
584 lhs = Expr {
585 kind: ExprKind::BinOp(op, Box::new(lhs), Box::new(rhs)),
586 span,
587 };
588 } else {
589 break;
590 }
591 }
592 Ok(lhs)
593 }
594
595 fn parse_unary(&mut self) -> Result<Expr, ParseError> {
596 if matches!(self.peek(), TokenKind::Tilde) {
597 let start = self.span();
598 self.advance();
599 let operand = self.parse_unary()?;
600 let span = start.merge(operand.span);
601 return Ok(Expr {
602 kind: ExprKind::UnaryNeg(Box::new(operand)),
603 span,
604 });
605 }
606 if matches!(self.peek(), TokenKind::Not) {
607 let start = self.span();
608 self.advance();
609 let operand = self.parse_unary()?;
610 let span = start.merge(operand.span);
611 return Ok(Expr {
612 kind: ExprKind::Not(Box::new(operand)),
613 span,
614 });
615 }
616 self.parse_app()
617 }
618
619 fn parse_app(&mut self) -> Result<Expr, ParseError> {
620 let mut lhs = self.parse_atom_expr()?;
621 while self.can_start_app_arg() {
622 let arg = self.parse_app_arg()?;
623 let span = lhs.span.merge(arg.span);
624 lhs = Expr {
625 kind: ExprKind::App(Box::new(lhs), Box::new(arg)),
626 span,
627 };
628 }
629 Ok(lhs)
630 }
631
632 fn parse_app_arg(&mut self) -> Result<Expr, ParseError> {
634 let start = self.span();
635 if matches!(self.peek(), TokenKind::Tilde) {
636 self.advance();
637 let operand = self.parse_atom_expr()?;
638 let span = start.merge(operand.span);
639 return Ok(Expr {
640 kind: ExprKind::UnaryNeg(Box::new(operand)),
641 span,
642 });
643 }
644 if matches!(self.peek(), TokenKind::Not) {
645 self.advance();
646 let operand = self.parse_atom_expr()?;
647 let span = start.merge(operand.span);
648 return Ok(Expr {
649 kind: ExprKind::Not(Box::new(operand)),
650 span,
651 });
652 }
653 self.parse_atom_expr()
654 }
655
656 fn parse_atom_expr(&mut self) -> Result<Expr, ParseError> {
657 let start = self.span();
658 match self.peek() {
659 TokenKind::IntLit(n) => {
660 let n = *n;
661 self.advance();
662 Ok(Expr {
663 kind: ExprKind::IntLit(n),
664 span: start,
665 })
666 }
667 TokenKind::FloatLit(f) => {
668 let f = *f;
669 self.advance();
670 Ok(Expr {
671 kind: ExprKind::FloatLit(f),
672 span: start,
673 })
674 }
675 TokenKind::StringLit(_) => {
676 let s = self.take_string_lit();
677 Ok(Expr {
678 kind: ExprKind::StringLit(s),
679 span: start,
680 })
681 }
682 TokenKind::CharLit(c) => {
683 let c = *c;
684 self.advance();
685 Ok(Expr {
686 kind: ExprKind::CharLit(c),
687 span: start,
688 })
689 }
690 TokenKind::True => {
691 self.advance();
692 Ok(Expr {
693 kind: ExprKind::BoolLit(true),
694 span: start,
695 })
696 }
697 TokenKind::False => {
698 self.advance();
699 Ok(Expr {
700 kind: ExprKind::BoolLit(false),
701 span: start,
702 })
703 }
704 TokenKind::Ident(_) => {
705 let name = self.take_symbol();
706 Ok(Expr {
707 kind: ExprKind::Var(name),
708 span: start,
709 })
710 }
711 TokenKind::UpperIdent(_) => {
712 let name = self.take_symbol();
713 Ok(Expr {
714 kind: ExprKind::Constructor(name),
715 span: start,
716 })
717 }
718 TokenKind::LParen => {
719 self.advance();
720 if self.eat(&TokenKind::RParen).is_some() {
721 return Ok(Expr {
722 kind: ExprKind::Unit,
723 span: start.merge(self.tokens[self.pos - 1].span),
724 });
725 }
726 let first = self.parse_expr()?;
727 if self.eat(&TokenKind::Comma).is_some() {
728 let mut elems = vec![first];
729 elems.push(self.parse_expr()?);
730 while self.eat(&TokenKind::Comma).is_some() {
731 elems.push(self.parse_expr()?);
732 }
733 let end = self.expect(&TokenKind::RParen, ")")?;
734 let span = start.merge(end);
735 Ok(Expr {
736 kind: ExprKind::Tuple(elems),
737 span,
738 })
739 } else {
740 let end = self.expect(&TokenKind::RParen, ")")?;
741 let span = start.merge(end);
742 Ok(Expr {
743 kind: ExprKind::Paren(Box::new(first)),
744 span,
745 })
746 }
747 }
748 TokenKind::LBracket => {
749 self.advance();
750 if self.eat(&TokenKind::RBracket).is_some() {
751 return Ok(Expr {
752 kind: ExprKind::List(vec![]),
753 span: start.merge(self.tokens[self.pos - 1].span),
754 });
755 }
756 let mut elems = vec![self.parse_expr()?];
757 while self.eat(&TokenKind::Comma).is_some() {
758 elems.push(self.parse_expr()?);
759 }
760 let end = self.expect(&TokenKind::RBracket, "]")?;
761 let span = start.merge(end);
762 Ok(Expr {
763 kind: ExprKind::List(elems),
764 span,
765 })
766 }
767 TokenKind::If => self.parse_if_expr(),
768 TokenKind::Let => self.parse_let_expr(),
769 TokenKind::Case => self.parse_case_expr(),
770 TokenKind::Fn => self.parse_fn_expr(),
771 TokenKind::Handle => self.parse_handle_expr(),
772 TokenKind::Perform => self.parse_perform_expr(),
773 TokenKind::Resume => self.parse_resume_expr(),
774 _ => Err(self.err("expected expression")),
775 }
776 }
777
778 fn parse_handle_expr(&mut self) -> Result<Expr, ParseError> {
779 let start = self.span();
780 self.advance(); let body = self.parse_expr()?;
782 self.expect(&TokenKind::With, "with")?;
783 self.expect(&TokenKind::Return, "return")?;
784 let (return_var, _) = self.expect_ident_or_wildcard()?;
785 self.expect(&TokenKind::Arrow, "=>")?;
786 let return_body = self.parse_expr()?;
787 let mut handlers = Vec::new();
788 while self.eat(&TokenKind::Bar).is_some() {
789 let hstart = self.span();
790 let (effect_name, _) = self.expect_upper_ident()?;
791 let (payload_var, _) = self.expect_ident_or_wildcard()?;
792 let (cont_var, _) = self.expect_ident_or_wildcard()?;
793 self.expect(&TokenKind::Arrow, "=>")?;
794 let hbody = self.parse_expr()?;
795 let hspan = hstart.merge(hbody.span);
796 handlers.push(EffectHandler {
797 effect_name,
798 payload_var,
799 cont_var,
800 body: hbody,
801 span: hspan,
802 });
803 }
804 let end_span = handlers.last().map(|h| h.span).unwrap_or(return_body.span);
805 let span = start.merge(end_span);
806 Ok(Expr {
807 kind: ExprKind::Handle {
808 body: Box::new(body),
809 return_var,
810 return_body: Box::new(return_body),
811 handlers,
812 },
813 span,
814 })
815 }
816
817 fn parse_perform_expr(&mut self) -> Result<Expr, ParseError> {
818 let start = self.span();
819 self.advance(); let (name, _) = self.expect_upper_ident()?;
821 let arg = self.parse_atom_expr()?;
822 let span = start.merge(arg.span);
823 Ok(Expr {
824 kind: ExprKind::Perform(name, Box::new(arg)),
825 span,
826 })
827 }
828
829 fn parse_resume_expr(&mut self) -> Result<Expr, ParseError> {
830 let start = self.span();
831 self.advance(); let cont = self.parse_atom_expr()?;
833 let arg = self.parse_atom_expr()?;
834 let span = start.merge(arg.span);
835 Ok(Expr {
836 kind: ExprKind::Resume(Box::new(cont), Box::new(arg)),
837 span,
838 })
839 }
840
841 fn parse_if_expr(&mut self) -> Result<Expr, ParseError> {
842 let start = self.span();
843 self.advance(); let cond = self.parse_expr()?;
845 self.expect(&TokenKind::Then, "then")?;
846 let then_br = self.parse_expr()?;
847 self.expect(&TokenKind::Else, "else")?;
848 let else_br = self.parse_expr()?;
849 let span = start.merge(else_br.span);
850 Ok(Expr {
851 kind: ExprKind::If(Box::new(cond), Box::new(then_br), Box::new(else_br)),
852 span,
853 })
854 }
855
856 fn parse_let_expr(&mut self) -> Result<Expr, ParseError> {
857 let start = self.span();
858 self.advance(); let mut decls = Vec::new();
860 while !matches!(self.peek(), TokenKind::In | TokenKind::Eof) {
861 decls.push(self.parse_decl()?);
862 }
863 self.expect(&TokenKind::In, "in")?;
864 let body = self.parse_expr()?;
865 let end = self.expect(&TokenKind::End, "end")?;
866 let span = start.merge(end);
867 Ok(Expr {
868 kind: ExprKind::Let(decls, Box::new(body)),
869 span,
870 })
871 }
872
873 fn parse_case_expr(&mut self) -> Result<Expr, ParseError> {
874 let start = self.span();
875 self.advance(); let scrutinee = self.parse_expr()?;
877 self.expect(&TokenKind::Of, "of")?;
878 self.eat(&TokenKind::Bar); let mut branches = Vec::new();
880 loop {
881 let pat = self.parse_pat()?;
882 self.expect(&TokenKind::Arrow, "=>")?;
883 let body = self.parse_expr()?;
884 branches.push((pat, body));
885 if self.eat(&TokenKind::Bar).is_none() {
886 break;
887 }
888 }
889 let last_span = branches.last().unwrap().1.span;
890 let span = start.merge(last_span);
891 Ok(Expr {
892 kind: ExprKind::Case(Box::new(scrutinee), branches),
893 span,
894 })
895 }
896
897 fn parse_fn_expr(&mut self) -> Result<Expr, ParseError> {
898 let start = self.span();
899 self.advance(); let pat = self.parse_pat()?;
901 self.expect(&TokenKind::Arrow, "=>")?;
902 let body = self.parse_expr()?;
903 let span = start.merge(body.span);
904 Ok(Expr {
905 kind: ExprKind::Fn(pat, Box::new(body)),
906 span,
907 })
908 }
909
910 fn parse_pat(&mut self) -> Result<Pat, ParseError> {
913 self.guard_depth()?;
914 let result = self.parse_pat_inner_dispatch();
915 self.unguard_depth();
916 result
917 }
918
919 fn parse_pat_inner_dispatch(&mut self) -> Result<Pat, ParseError> {
920 let pat = self.parse_as_pat()?;
921 if self.eat(&TokenKind::Colon).is_some() {
922 let ty = self.parse_type_expr()?;
923 let span = pat.span.merge(ty.span);
924 Ok(Pat {
925 kind: PatKind::Ann(Box::new(pat), ty),
926 span,
927 })
928 } else {
929 Ok(pat)
930 }
931 }
932
933 fn parse_as_pat(&mut self) -> Result<Pat, ParseError> {
934 if matches!(self.peek(), TokenKind::Ident(_))
936 && self.pos + 1 < self.tokens.len()
937 && matches!(self.tokens[self.pos + 1].kind, TokenKind::As)
938 {
939 let start = self.span();
940 let name = self.take_symbol(); self.advance(); let inner = self.parse_as_pat()?;
943 let span = start.merge(inner.span);
944 return Ok(Pat {
945 kind: PatKind::As(name, Box::new(inner)),
946 span,
947 });
948 }
949 self.parse_cons_pat()
950 }
951
952 fn parse_cons_pat(&mut self) -> Result<Pat, ParseError> {
953 let lhs = self.parse_app_pat()?;
954 if self.eat(&TokenKind::ColonColon).is_some() {
955 let rhs = self.parse_cons_pat()?; let span = lhs.span.merge(rhs.span);
957 Ok(Pat {
958 kind: PatKind::Cons(Box::new(lhs), Box::new(rhs)),
959 span,
960 })
961 } else {
962 Ok(lhs)
963 }
964 }
965
966 fn parse_app_pat(&mut self) -> Result<Pat, ParseError> {
967 if matches!(self.peek(), TokenKind::UpperIdent(_)) {
968 let start = self.span();
969 let name = self.take_symbol();
970 if self.can_start_atom_pat() {
971 let payload = self.parse_atom_pat()?;
972 let span = start.merge(payload.span);
973 Ok(Pat {
974 kind: PatKind::Constructor(name, Some(Box::new(payload))),
975 span,
976 })
977 } else {
978 Ok(Pat {
979 kind: PatKind::Constructor(name, None),
980 span: start,
981 })
982 }
983 } else {
984 self.parse_atom_pat()
985 }
986 }
987
988 fn parse_atom_pat(&mut self) -> Result<Pat, ParseError> {
989 let start = self.span();
990 match self.peek() {
991 TokenKind::Underscore => {
992 self.advance();
993 Ok(Pat {
994 kind: PatKind::Wildcard,
995 span: start,
996 })
997 }
998 TokenKind::Ident(_) => {
999 let name = self.take_symbol();
1000 Ok(Pat {
1001 kind: PatKind::Var(name),
1002 span: start,
1003 })
1004 }
1005 TokenKind::UpperIdent(_) => {
1006 let name = self.take_symbol();
1007 Ok(Pat {
1008 kind: PatKind::Constructor(name, None),
1009 span: start,
1010 })
1011 }
1012 TokenKind::IntLit(n) => {
1013 let n = *n;
1014 self.advance();
1015 Ok(Pat {
1016 kind: PatKind::IntLit(n),
1017 span: start,
1018 })
1019 }
1020 TokenKind::FloatLit(f) => {
1021 let f = *f;
1022 self.advance();
1023 Ok(Pat {
1024 kind: PatKind::FloatLit(f),
1025 span: start,
1026 })
1027 }
1028 TokenKind::StringLit(_) => {
1029 let s = self.take_string_lit();
1030 Ok(Pat {
1031 kind: PatKind::StringLit(s),
1032 span: start,
1033 })
1034 }
1035 TokenKind::CharLit(c) => {
1036 let c = *c;
1037 self.advance();
1038 Ok(Pat {
1039 kind: PatKind::CharLit(c),
1040 span: start,
1041 })
1042 }
1043 TokenKind::True => {
1044 self.advance();
1045 Ok(Pat {
1046 kind: PatKind::BoolLit(true),
1047 span: start,
1048 })
1049 }
1050 TokenKind::False => {
1051 self.advance();
1052 Ok(Pat {
1053 kind: PatKind::BoolLit(false),
1054 span: start,
1055 })
1056 }
1057 TokenKind::Tilde => {
1058 self.advance();
1059 match self.peek() {
1060 TokenKind::IntLit(n) => {
1061 let n = *n;
1062 let end = self.span();
1063 self.advance();
1064 Ok(Pat {
1065 kind: PatKind::IntLit(-n),
1066 span: start.merge(end),
1067 })
1068 }
1069 TokenKind::FloatLit(f) => {
1070 let f = *f;
1071 let end = self.span();
1072 self.advance();
1073 Ok(Pat {
1074 kind: PatKind::FloatLit(-f),
1075 span: start.merge(end),
1076 })
1077 }
1078 _ => Err(self.err("expected number after ~ in pattern")),
1079 }
1080 }
1081 TokenKind::LParen => {
1082 self.advance();
1083 if self.eat(&TokenKind::RParen).is_some() {
1084 return Ok(Pat {
1085 kind: PatKind::Unit,
1086 span: start.merge(self.tokens[self.pos - 1].span),
1087 });
1088 }
1089 let first = self.parse_pat()?;
1090 if self.eat(&TokenKind::Comma).is_some() {
1091 let mut elems = vec![first];
1092 elems.push(self.parse_pat()?);
1093 while self.eat(&TokenKind::Comma).is_some() {
1094 elems.push(self.parse_pat()?);
1095 }
1096 let end = self.expect(&TokenKind::RParen, ")")?;
1097 let span = start.merge(end);
1098 Ok(Pat {
1099 kind: PatKind::Tuple(elems),
1100 span,
1101 })
1102 } else {
1103 let end = self.expect(&TokenKind::RParen, ")")?;
1104 let span = start.merge(end);
1105 Ok(Pat {
1106 kind: PatKind::Paren(Box::new(first)),
1107 span,
1108 })
1109 }
1110 }
1111 TokenKind::LBracket => {
1112 self.advance();
1113 if self.eat(&TokenKind::RBracket).is_some() {
1114 return Ok(Pat {
1115 kind: PatKind::List(vec![]),
1116 span: start.merge(self.tokens[self.pos - 1].span),
1117 });
1118 }
1119 let mut elems = vec![self.parse_pat()?];
1120 while self.eat(&TokenKind::Comma).is_some() {
1121 elems.push(self.parse_pat()?);
1122 }
1123 let end = self.expect(&TokenKind::RBracket, "]")?;
1124 let span = start.merge(end);
1125 Ok(Pat {
1126 kind: PatKind::List(elems),
1127 span,
1128 })
1129 }
1130 _ => Err(self.err("expected pattern")),
1131 }
1132 }
1133
1134 fn parse_type_expr(&mut self) -> Result<TypeExpr, ParseError> {
1137 self.guard_depth()?;
1138 let result = self.parse_arrow_type();
1139 self.unguard_depth();
1140 result
1141 }
1142
1143 fn parse_arrow_type(&mut self) -> Result<TypeExpr, ParseError> {
1144 let lhs = self.parse_tuple_type()?;
1145 if self.eat(&TokenKind::ThinArrow).is_some() {
1146 let rhs = self.parse_arrow_type()?; let span = lhs.span.merge(rhs.span);
1148 Ok(TypeExpr {
1149 kind: TypeExprKind::Arrow(Box::new(lhs), Box::new(rhs)),
1150 span,
1151 })
1152 } else {
1153 Ok(lhs)
1154 }
1155 }
1156
1157 fn parse_tuple_type(&mut self) -> Result<TypeExpr, ParseError> {
1158 let first = self.parse_app_type()?;
1159 if matches!(self.peek(), TokenKind::Star) {
1160 let mut elems = vec![first];
1161 while self.eat(&TokenKind::Star).is_some() {
1162 elems.push(self.parse_app_type()?);
1163 }
1164 let span = elems[0].span.merge(elems.last().unwrap().span);
1165 Ok(TypeExpr {
1166 kind: TypeExprKind::Tuple(elems),
1167 span,
1168 })
1169 } else {
1170 Ok(first)
1171 }
1172 }
1173
1174 fn parse_app_type(&mut self) -> Result<TypeExpr, ParseError> {
1175 let mut ty = self.parse_atom_type()?;
1176 while matches!(self.peek(), TokenKind::Ident(_) | TokenKind::UpperIdent(_)) {
1177 let end = self.span();
1178 let name = self.take_symbol();
1179 let (args, base_span) = match ty.kind {
1180 TypeExprKind::Tuple(elems) => (elems, ty.span),
1181 _ => {
1182 let span = ty.span;
1183 (vec![ty], span)
1184 }
1185 };
1186 let span = base_span.merge(end);
1187 ty = TypeExpr {
1188 kind: TypeExprKind::App(name, args),
1189 span,
1190 };
1191 }
1192 Ok(ty)
1193 }
1194
1195 fn parse_atom_type(&mut self) -> Result<TypeExpr, ParseError> {
1196 let start = self.span();
1197 match self.peek() {
1198 TokenKind::TyVar(_) => {
1199 let name = self.take_symbol();
1200 Ok(TypeExpr {
1201 kind: TypeExprKind::Var(name),
1202 span: start,
1203 })
1204 }
1205 TokenKind::Ident(_) | TokenKind::UpperIdent(_) => {
1206 let name = self.take_symbol();
1207 Ok(TypeExpr {
1208 kind: TypeExprKind::Named(name),
1209 span: start,
1210 })
1211 }
1212 TokenKind::LParen => {
1213 self.advance();
1214 let first = self.parse_type_expr()?;
1215 if self.eat(&TokenKind::Comma).is_some() {
1216 let mut elems = vec![first];
1218 elems.push(self.parse_type_expr()?);
1219 while self.eat(&TokenKind::Comma).is_some() {
1220 elems.push(self.parse_type_expr()?);
1221 }
1222 let end = self.expect(&TokenKind::RParen, ")")?;
1223 let span = start.merge(end);
1224 Ok(TypeExpr {
1225 kind: TypeExprKind::Tuple(elems),
1226 span,
1227 })
1228 } else {
1229 let end = self.expect(&TokenKind::RParen, ")")?;
1230 let span = start.merge(end);
1231 Ok(TypeExpr {
1232 kind: TypeExprKind::Paren(Box::new(first)),
1233 span,
1234 })
1235 }
1236 }
1237 _ => Err(self.err("expected type")),
1238 }
1239 }
1240}
1241
1242#[cfg(test)]
1243mod tests {
1244 use super::*;
1245 use crate::lexer::Lexer;
1246
1247 fn parse(input: &str) -> Program {
1248 let mut lexer = Lexer::new(input, 0);
1249 let tokens = lexer.tokenize().expect("lex error");
1250 let mut parser = Parser::new(tokens);
1251 parser.parse_program().expect("parse error")
1252 }
1253
1254 #[allow(dead_code)]
1255 fn parse_err(input: &str) -> String {
1256 let mut lexer = Lexer::new(input, 0);
1257 let tokens = lexer.tokenize().expect("lex error");
1258 let mut parser = Parser::new(tokens);
1259 parser.parse_program().unwrap_err().message
1260 }
1261
1262 #[test]
1263 fn test_val_binding() {
1264 let prog = parse("val x = 42");
1265 assert_eq!(prog.decls.len(), 1);
1266 assert!(matches!(&prog.decls[0].kind, DeclKind::Val(_, _)));
1267 }
1268
1269 #[test]
1270 fn test_val_rec() {
1271 let prog = parse("val rec f = fn x => x");
1272 if let DeclKind::ValRec(name, _) = &prog.decls[0].kind {
1273 assert_eq!(prog.interner.resolve(*name), "f");
1274 } else {
1275 panic!("expected ValRec");
1276 }
1277 }
1278
1279 #[test]
1280 fn test_val_rec_requires_fn() {
1281 assert_eq!(
1282 parse_err("val rec x = 1"),
1283 "val rec requires fn on the right-hand side"
1284 );
1285 }
1286
1287 #[test]
1288 fn test_app_with_unary_neg() {
1289 let prog = parse("val x = f ~1");
1291 if let DeclKind::Val(_, ref expr) = prog.decls[0].kind {
1292 if let ExprKind::App(_, ref arg) = expr.kind {
1293 assert!(matches!(&arg.kind, ExprKind::UnaryNeg(_)));
1294 } else {
1295 panic!("expected App");
1296 }
1297 }
1298 }
1299
1300 #[test]
1301 fn test_app_with_not() {
1302 let prog = parse("val x = f not true");
1303 if let DeclKind::Val(_, ref expr) = prog.decls[0].kind {
1304 if let ExprKind::App(_, ref arg) = expr.kind {
1305 assert!(matches!(&arg.kind, ExprKind::Not(_)));
1306 } else {
1307 panic!("expected App");
1308 }
1309 }
1310 }
1311
1312 #[test]
1313 fn test_constructor_with_unary_neg() {
1314 let prog = parse("val x = Some ~1");
1315 if let DeclKind::Val(_, ref expr) = prog.decls[0].kind {
1316 if let ExprKind::App(_, ref arg) = expr.kind {
1317 assert!(matches!(&arg.kind, ExprKind::UnaryNeg(_)));
1318 } else {
1319 panic!("expected App");
1320 }
1321 }
1322 }
1323
1324 #[test]
1325 fn test_fun_simple() {
1326 let prog = parse("fun add x y = x + y");
1327 if let DeclKind::Fun(bindings) = &prog.decls[0].kind {
1328 assert_eq!(prog.interner.resolve(bindings[0].name), "add");
1329 assert_eq!(bindings[0].clauses[0].pats.len(), 2);
1330 } else {
1331 panic!("expected fun");
1332 }
1333 }
1334
1335 #[test]
1336 fn test_fun_clausal() {
1337 let prog = parse("fun f 0 = 1 | f n = n");
1338 if let DeclKind::Fun(bindings) = &prog.decls[0].kind {
1339 assert_eq!(bindings[0].clauses.len(), 2);
1340 } else {
1341 panic!("expected fun");
1342 }
1343 }
1344
1345 #[test]
1346 fn test_fun_mutual() {
1347 let prog = parse("fun f x = g x and g y = f y");
1348 if let DeclKind::Fun(bindings) = &prog.decls[0].kind {
1349 assert_eq!(bindings.len(), 2);
1350 assert_eq!(prog.interner.resolve(bindings[0].name), "f");
1351 assert_eq!(prog.interner.resolve(bindings[1].name), "g");
1352 } else {
1353 panic!("expected fun");
1354 }
1355 }
1356
1357 #[test]
1358 fn test_datatype_simple() {
1359 let prog = parse("datatype shape = Circle of Float | Rect of Float * Float");
1360 if let DeclKind::Datatype(dt) = &prog.decls[0].kind {
1361 assert_eq!(prog.interner.resolve(dt.name), "shape");
1362 assert_eq!(dt.tyvars.len(), 0);
1363 assert_eq!(dt.constructors.len(), 2);
1364 } else {
1365 panic!("expected datatype");
1366 }
1367 }
1368
1369 #[test]
1370 fn test_datatype_parameterized() {
1371 let prog = parse("datatype 'a option = None | Some of 'a");
1372 if let DeclKind::Datatype(dt) = &prog.decls[0].kind {
1373 let tyvars: Vec<&str> = dt
1374 .tyvars
1375 .iter()
1376 .map(|s| prog.interner.resolve(*s))
1377 .collect();
1378 assert_eq!(tyvars, vec!["'a"]);
1379 assert_eq!(dt.constructors.len(), 2);
1380 } else {
1381 panic!("expected datatype");
1382 }
1383 }
1384
1385 #[test]
1386 fn test_datatype_multi_param() {
1387 let prog = parse("datatype ('a, 'b) either = Left of 'a | Right of 'b");
1388 if let DeclKind::Datatype(dt) = &prog.decls[0].kind {
1389 let tyvars: Vec<&str> = dt
1390 .tyvars
1391 .iter()
1392 .map(|s| prog.interner.resolve(*s))
1393 .collect();
1394 assert_eq!(tyvars, vec!["'a", "'b"]);
1395 } else {
1396 panic!("expected datatype");
1397 }
1398 }
1399
1400 #[test]
1401 fn test_type_alias() {
1402 let prog = parse("type point = Float * Float");
1403 assert!(matches!(&prog.decls[0].kind, DeclKind::TypeAlias(_)));
1404 }
1405
1406 #[test]
1407 fn test_use_decl() {
1408 let prog = parse(r#"use "foo.hml""#);
1409 assert!(matches!(&prog.decls[0].kind, DeclKind::Use(path) if path == "foo.hml"));
1410 }
1411
1412 #[test]
1413 fn test_let_expr() {
1414 let prog = parse("val x = let val a = 1 in a + 2 end");
1415 assert!(matches!(&prog.decls[0].kind, DeclKind::Val(_, _)));
1416 }
1417
1418 #[test]
1419 fn test_case_expr() {
1420 let prog = parse("val x = case y of 0 => 1 | n => n");
1421 assert!(matches!(&prog.decls[0].kind, DeclKind::Val(_, _)));
1422 }
1423
1424 #[test]
1425 fn test_fn_expr() {
1426 let prog = parse("val f = fn x => x + 1");
1427 assert!(matches!(&prog.decls[0].kind, DeclKind::Val(_, _)));
1428 }
1429
1430 #[test]
1431 fn test_if_expr() {
1432 let prog = parse("val x = if true then 1 else 2");
1433 assert!(matches!(&prog.decls[0].kind, DeclKind::Val(_, _)));
1434 }
1435
1436 #[test]
1437 fn test_tuple_expr() {
1438 let prog = parse("val x = (1, 2, 3)");
1439 if let DeclKind::Val(_, ref expr) = prog.decls[0].kind {
1440 assert!(matches!(&expr.kind, ExprKind::Tuple(elems) if elems.len() == 3));
1441 }
1442 }
1443
1444 #[test]
1445 fn test_list_expr() {
1446 let prog = parse("val x = [1, 2, 3]");
1447 if let DeclKind::Val(_, ref expr) = prog.decls[0].kind {
1448 assert!(matches!(&expr.kind, ExprKind::List(elems) if elems.len() == 3));
1449 }
1450 }
1451
1452 #[test]
1453 fn test_cons_expr() {
1454 let prog = parse("val x = 1 :: 2 :: []");
1455 if let DeclKind::Val(_, ref expr) = prog.decls[0].kind {
1456 assert!(matches!(&expr.kind, ExprKind::Cons(_, _)));
1457 }
1458 }
1459
1460 #[test]
1461 fn test_operator_precedence() {
1462 let prog = parse("val x = 1 + 2 * 3");
1464 if let DeclKind::Val(_, ref expr) = prog.decls[0].kind {
1465 if let ExprKind::BinOp(BinOp::AddInt, _, ref rhs) = expr.kind {
1466 assert!(matches!(&rhs.kind, ExprKind::BinOp(BinOp::MulInt, _, _)));
1467 } else {
1468 panic!("expected AddInt at top");
1469 }
1470 }
1471 }
1472
1473 #[test]
1474 fn test_application() {
1475 let prog = parse("val x = f a b");
1476 if let DeclKind::Val(_, ref expr) = prog.decls[0].kind {
1477 if let ExprKind::App(ref func, _) = expr.kind {
1479 assert!(matches!(&func.kind, ExprKind::App(_, _)));
1480 } else {
1481 panic!("expected App");
1482 }
1483 }
1484 }
1485
1486 #[test]
1487 fn test_pattern_cons() {
1488 let prog = parse("val (x :: xs) = [1, 2]");
1489 if let DeclKind::Val(ref pat, _) = prog.decls[0].kind {
1490 if let PatKind::Paren(ref inner) = pat.kind {
1491 assert!(matches!(&inner.kind, PatKind::Cons(_, _)));
1492 }
1493 }
1494 }
1495
1496 #[test]
1497 fn test_pattern_constructor() {
1498 let prog = parse("fun f (Some x) = x | f None = 0");
1499 if let DeclKind::Fun(ref bindings) = prog.decls[0].kind {
1500 assert_eq!(bindings[0].clauses.len(), 2);
1501 }
1502 }
1503
1504 #[test]
1505 fn test_type_annotation() {
1506 let prog = parse("val x = (42 : Int)");
1507 assert!(matches!(&prog.decls[0].kind, DeclKind::Val(_, _)));
1508 }
1509
1510 #[test]
1511 fn test_arrow_type() {
1512 let prog = parse("type f = Int -> Bool");
1513 if let DeclKind::TypeAlias(ref ta) = prog.decls[0].kind {
1514 assert!(matches!(&ta.ty.kind, TypeExprKind::Arrow(_, _)));
1515 }
1516 }
1517
1518 #[test]
1519 fn test_type_app() {
1520 let prog = parse("type xs = Int list");
1521 if let DeclKind::TypeAlias(ref ta) = prog.decls[0].kind {
1522 if let TypeExprKind::App(sym, _) = &ta.ty.kind {
1523 assert_eq!(prog.interner.resolve(*sym), "list");
1524 } else {
1525 panic!("expected App");
1526 }
1527 }
1528 }
1529
1530 #[test]
1531 fn test_local_decl() {
1532 let prog = parse("local val x = 1 in val y = x end");
1533 assert!(matches!(&prog.decls[0].kind, DeclKind::Local(_, _)));
1534 }
1535
1536 #[test]
1537 fn test_negative_pattern() {
1538 let prog = parse("fun f ~1 = true | f _ = false");
1539 if let DeclKind::Fun(ref bindings) = prog.decls[0].kind {
1540 if let PatKind::IntLit(n) = &bindings[0].clauses[0].pats[0].kind {
1541 assert_eq!(*n, -1);
1542 }
1543 }
1544 }
1545
1546 #[test]
1547 fn test_as_pattern() {
1548 let prog = parse("val (x as Some _) = y");
1549 if let DeclKind::Val(ref pat, _) = prog.decls[0].kind {
1550 if let PatKind::Paren(ref inner) = pat.kind {
1551 if let PatKind::As(sym, _) = &inner.kind {
1552 assert_eq!(prog.interner.resolve(*sym), "x");
1553 } else {
1554 panic!("expected As");
1555 }
1556 }
1557 }
1558 }
1559
1560 #[test]
1561 fn test_float_operators() {
1562 let prog = parse("val x = 1.0 +. 2.0 *. 3.0");
1563 if let DeclKind::Val(_, ref expr) = prog.decls[0].kind {
1564 if let ExprKind::BinOp(BinOp::AddFloat, _, ref rhs) = expr.kind {
1565 assert!(matches!(&rhs.kind, ExprKind::BinOp(BinOp::MulFloat, _, _)));
1566 } else {
1567 panic!("expected AddFloat");
1568 }
1569 }
1570 }
1571
1572 #[test]
1573 fn test_unit_expr() {
1574 let prog = parse("val x = ()");
1575 if let DeclKind::Val(_, ref expr) = prog.decls[0].kind {
1576 assert!(matches!(&expr.kind, ExprKind::Unit));
1577 }
1578 }
1579
1580 #[test]
1581 fn test_empty_list() {
1582 let prog = parse("val x = []");
1583 if let DeclKind::Val(_, ref expr) = prog.decls[0].kind {
1584 assert!(matches!(&expr.kind, ExprKind::List(elems) if elems.is_empty()));
1585 }
1586 }
1587
1588 #[test]
1589 fn test_orelse_right_assoc() {
1590 let prog = parse("val x = a orelse b orelse c");
1592 if let DeclKind::Val(_, ref expr) = prog.decls[0].kind {
1593 if let ExprKind::BinOp(BinOp::Orelse, _, ref rhs) = expr.kind {
1594 assert!(matches!(&rhs.kind, ExprKind::BinOp(BinOp::Orelse, _, _)));
1595 } else {
1596 panic!("expected Orelse at top");
1597 }
1598 }
1599 }
1600
1601 #[test]
1602 fn test_andalso_right_assoc() {
1603 let prog = parse("val x = a andalso b andalso c");
1604 if let DeclKind::Val(_, ref expr) = prog.decls[0].kind {
1605 if let ExprKind::BinOp(BinOp::Andalso, _, ref rhs) = expr.kind {
1606 assert!(matches!(&rhs.kind, ExprKind::BinOp(BinOp::Andalso, _, _)));
1607 } else {
1608 panic!("expected Andalso at top");
1609 }
1610 }
1611 }
1612
1613 #[test]
1614 fn test_complex_program() {
1615 let src = r#"
1617 datatype 'a option = None | Some of 'a
1618
1619 fun map_option f opt =
1620 case opt of
1621 None => None
1622 | Some x => Some (f x)
1623
1624 val result = map_option (fn x => x + 1) (Some 42)
1625 "#;
1626 let prog = parse(src);
1627 assert_eq!(prog.decls.len(), 3);
1628 }
1629}