1use crate::{
2 fun::{
3 parser::{is_num_char, make_ctr_type, make_fn_type, Indent, ParseResult, ParserCommons},
4 Adt, AdtCtr, CtrField, HvmDefinition, Name, Num, Op, Source, SourceKind, Type, STRINGS,
5 },
6 imp::{AssignPattern, Definition, Expr, InPlaceOp, MatchArm, Stmt},
7 maybe_grow,
8};
9use TSPL::Parser;
10
11pub struct ImpParser<'i> {
12 pub file: Name,
13 pub input: &'i str,
14 pub index: usize,
15 pub builtin: bool,
16}
17
18impl<'a> ImpParser<'a> {
19 pub fn new(file: Name, input: &'a str, builtin: bool) -> Self {
20 Self { file, input, index: 0, builtin }
21 }
22
23 pub fn parse_function_def(&mut self, indent: Indent) -> ParseResult<(Definition, Indent)> {
24 if indent != Indent::Val(0) {
27 let msg = "Indentation error. Functions defined with 'def' must be at the start of the line.";
28 let idx = *self.index();
29 return self.with_ctx(Err(msg), idx..idx + 1);
30 }
31 let (mut def, nxt_indent) = self.parse_def_aux(indent)?;
33 def.source.kind = if self.builtin { SourceKind::Builtin } else { SourceKind::User };
34 Ok((def, nxt_indent))
35 }
36
37 pub fn parse_type_def(&mut self, mut indent: Indent) -> ParseResult<(Adt, Indent)> {
38 if indent != Indent::Val(0) {
39 let msg = "Indentation error. Types defined with 'type' must be at the start of the line.";
40 let idx = *self.index();
41 return self.with_ctx(Err(msg), idx..idx + 1);
42 }
43 let ini_idx = *self.index();
44
45 self.parse_keyword("type")?;
46 self.skip_trivia_inline()?;
47
48 let type_name = self.parse_restricted_name("datatype")?;
49 self.skip_trivia_inline()?;
50
51 let type_vars = if self.try_consume_exactly("(") {
52 self.list_like(|p| p.parse_var_name(), "", ")", ",", true, 0)?
53 } else {
54 vec![]
55 };
56 self.skip_trivia_inline()?;
57
58 self.consume_exactly(":")?;
59 self.consume_new_line()?;
60 indent.enter_level();
61 self.consume_indent_exactly(indent)?;
62
63 let mut ctrs = Vec::new();
64 let mut nxt_indent = indent;
65 while nxt_indent == indent {
66 ctrs.push(self.parse_type_def_variant(&type_name, &type_vars)?);
67 if !self.is_eof() {
68 self.consume_new_line()?;
69 }
70 nxt_indent = self.consume_indent_at_most(indent)?;
71 }
72 indent.exit_level();
73
74 let ctrs = ctrs.into_iter().map(|ctr| (ctr.name.clone(), ctr)).collect();
75 let source = Source::from_file_span(&self.file, self.input, ini_idx..self.index, self.builtin);
76 let adt = Adt { name: type_name, vars: type_vars, ctrs, source };
77
78 Ok((adt, nxt_indent))
79 }
80
81 pub fn parse_object(&mut self, indent: Indent) -> ParseResult<(Adt, Indent)> {
82 if indent != Indent::Val(0) {
84 let msg = "Indentation error. Types defined with 'object' must be at the start of the line.";
85 let idx = *self.index();
86 return self.with_ctx(Err(msg), idx..idx + 1);
87 }
88 let ini_idx = *self.index();
89
90 self.parse_keyword("object")?;
91 self.skip_trivia_inline()?;
92
93 let name = self.parse_top_level_name()?;
94 self.skip_trivia_inline()?;
95
96 let type_vars = if self.starts_with("(") {
97 self.list_like(|p| p.parse_var_name(), "(", ")", ",", true, 0)?
98 } else {
99 vec![]
100 };
101 self.skip_trivia_inline()?;
102
103 let fields = if self.starts_with("{") {
104 self.list_like(|p| p.parse_variant_field(), "{", "}", ",", true, 0)?
105 } else {
106 vec![]
107 };
108 let field_types = fields.iter().map(|f| f.typ.clone()).collect::<Vec<_>>();
109
110 let end_idx = *self.index();
111 self.check_repeated_ctr_fields(&fields, &name, ini_idx..end_idx)?;
112
113 if !self.is_eof() {
114 self.consume_new_line()?;
115 }
116 let nxt_indent = self.advance_newlines()?;
117
118 let typ = make_ctr_type(name.clone(), &field_types, &type_vars);
119 let ctr = AdtCtr { name: name.clone(), typ, fields };
120
121 let ctrs = [(name.clone(), ctr)].into_iter().collect();
122 let source = Source::from_file_span(&self.file, self.input, ini_idx..end_idx, self.builtin);
123 let adt = Adt { name, vars: type_vars, ctrs, source };
124 Ok((adt, nxt_indent))
125 }
126
127 pub fn parse_hvm(&mut self) -> ParseResult<(HvmDefinition, Indent)> {
128 let ini_idx = *self.index();
129
130 self.parse_keyword("hvm")?;
131 self.skip_trivia_inline()?;
132
133 let name = self.parse_var_name()?;
134 self.skip_trivia_inline()?;
135
136 let typ = self.parse_return_type()?.unwrap_or(Type::Any);
137 let typ = make_fn_type(vec![], typ);
138 self.skip_trivia_inline()?;
139
140 self.consume_exactly(":")?;
141 self.consume_new_line()?;
142
143 let net_idx = *self.index();
145 let mut p = hvm::ast::CoreParser::new(&self.input[net_idx..]);
146 let body = p.parse_net()?;
147 *self.index() = net_idx + *p.index();
148
149 let source = Source::from_file_span(&self.file, self.input, ini_idx..self.index, self.builtin);
150 let def = HvmDefinition { name: name.clone(), typ, body, source };
151 let nxt_indent = self.advance_newlines()?;
152 Ok((def, nxt_indent))
153 }
154
155 fn parse_type_def_variant(&mut self, type_name: &Name, type_vars: &[Name]) -> ParseResult<AdtCtr> {
156 let ini_idx = *self.index();
157 let name = self.parse_top_level_name()?;
158 let name = Name::new(format!("{type_name}/{name}"));
159 self.skip_trivia_inline()?;
160
161 let fields = if self.try_consume_exactly("{") {
162 self.list_like(|p| p.parse_variant_field(), "", "}", ",", true, 0)?
163 } else {
164 vec![]
165 };
166 let field_types = fields.iter().map(|f| f.typ.clone()).collect::<Vec<_>>();
167 let end_idx = *self.index();
168 self.check_repeated_ctr_fields(&fields, &name, ini_idx..end_idx)?;
169
170 let typ = make_ctr_type(type_name.clone(), &field_types, type_vars);
171 Ok(AdtCtr { name, typ, fields })
172 }
173
174 fn parse_variant_field(&mut self) -> ParseResult<CtrField> {
175 let rec = self.try_consume_exactly("~");
176 self.skip_trivia_inline()?;
177
178 let nam = self.parse_var_name()?;
179 self.skip_trivia_inline()?;
180
181 let typ = if self.try_consume_exactly(":") { self.parse_type_expr()? } else { Type::Any };
182
183 Ok(CtrField { nam, typ, rec })
184 }
185
186 fn parse_primary_expr(&mut self, inline: bool) -> ParseResult<Expr> {
187 if inline {
188 self.skip_trivia_inline()?;
189 } else {
190 self.skip_trivia();
191 }
192 if self.try_parse_keyword("lambda") | self.try_consume_exactly("λ") {
193 fn parse_lam_var(p: &mut ImpParser) -> ParseResult<(Name, bool)> {
194 if p.starts_with("$") {
195 p.advance_one();
196 Ok((p.parse_var_name()?, true))
197 } else {
198 Ok((p.parse_var_name()?, false))
199 }
200 }
201 let names = self.list_like(|p| parse_lam_var(p), "", ":", ",", false, 1)?;
202 let bod = self.parse_expr(inline, false)?;
203 Ok(Expr::Lam { names, bod: Box::new(bod) })
204 } else if self.starts_with("(") {
205 self.advance_one();
206 let expr = self.parse_expr(inline, true)?;
207 self.consume(")")?;
208 Ok(expr)
209 } else if self.starts_with("{") {
210 self.parse_map_or_sup()
212 } else if self.starts_with("[") {
213 self.parse_list_or_comprehension()
215 } else if self.starts_with("![") {
216 self.parse_tree_node()
218 } else if self.starts_with("!") {
219 self.parse_tree_leaf(inline)
221 } else if self.starts_with("`") {
222 Ok(Expr::Num { val: Num::U24(self.parse_quoted_symbol()?) })
224 } else if self.starts_with("\"") {
225 Ok(Expr::Str { val: STRINGS.get(self.parse_quoted_string()?) })
227 } else if self.starts_with("'") {
228 Ok(Expr::Num { val: Num::U24(self.parse_quoted_char()? as u32 & 0x00ff_ffff) })
230 } else if self.starts_with("$") {
231 self.advance_one();
233 Ok(Expr::Chn { nam: self.parse_var_name()? })
234 } else if self.starts_with("*") {
235 self.advance_one();
237 Ok(Expr::Era)
238 } else if let Some(c) = self.peek_one() {
239 if is_num_char(c) {
240 Ok(Expr::Num { val: self.parse_number()? })
242 } else {
243 let nam = self.labelled(|p| p.parse_var_name(), "expression")?;
245 Ok(Expr::Var { nam })
246 }
247 } else {
248 self.expected("expression")?
249 }
250 }
251
252 fn call_or_postfix(&mut self, inline: bool) -> ParseResult<Expr> {
253 let ini_idx = *self.index();
254 let base = self.parse_primary_expr(inline)?;
255 if inline {
256 self.skip_trivia_inline()?;
257 } else {
258 self.skip_trivia();
259 }
260
261 if self.starts_with("(") {
263 self.advance_one();
264 let mut args = Vec::new();
265 let mut kwargs = Vec::new();
266 let mut must_be_named = false;
267 while !self.starts_with(")") {
268 let ini_idx = *self.index();
269 let (bnd, arg) = self.parse_named_arg()?;
270 let end_idx = *self.index();
271 if let Some(bnd) = bnd {
272 must_be_named = true;
273 kwargs.push((bnd, arg));
274 } else if must_be_named {
275 let msg = "Positional arguments are not allowed to go after named arguments.".to_string();
276 return self.with_ctx(Err(msg), ini_idx..end_idx);
277 } else {
278 args.push(arg);
279 }
280 if self.starts_with(",") {
281 self.consume(",")?;
282 } else {
283 break;
284 }
285 }
286 self.consume(")")?;
287 if args.is_empty() && kwargs.is_empty() {
288 return Ok(base);
289 } else {
290 return Ok(Expr::Call { fun: Box::new(base), args, kwargs });
291 }
292 }
293
294 if self.starts_with("[") {
296 if let Expr::Var { nam } = base {
297 self.advance_one();
298 let key = self.parse_expr(inline, false)?;
299 self.consume("]")?;
300 return Ok(Expr::MapGet { nam, key: Box::new(key) });
301 } else {
302 let end_idx = *self.index();
303 return self.expected_spanned("Map variable name", ini_idx..end_idx);
304 }
305 }
306
307 if self.starts_with("{") {
309 if let Expr::Var { nam } = base {
310 let kwargs = self.list_like(|p| p.data_kwarg(), "{", "}", ",", true, 0)?;
311 return Ok(Expr::Ctr { name: nam, args: Vec::new(), kwargs });
312 } else {
313 let end_idx = *self.index();
314 return self.expected_spanned("Constructor name", ini_idx..end_idx);
315 }
316 }
317
318 Ok(base)
320 }
321
322 fn parse_map_or_sup(&mut self) -> ParseResult<Expr> {
323 self.advance_one();
324 if self.try_consume("}") {
326 return Ok(Expr::Map { entries: vec![] });
327 }
328 let head = self.parse_expr(false, false)?;
329 self.skip_trivia();
330 if self.try_consume(",") {
331 self.parse_sup(head)
332 } else if self.try_consume(":") {
333 self.parse_map_init(head)
334 } else {
335 self.expected("',' or ':'")
336 }
337 }
338
339 fn parse_map_init(&mut self, head: Expr) -> ParseResult<Expr> {
340 let mut entries = Vec::new();
341 let val = self.parse_expr(false, false)?;
342 entries.push((head, val));
343 self.skip_trivia();
344 if !self.starts_with("}") {
345 self.consume(",")?;
346 }
347 let tail = self.list_like(|p| p.parse_map_entry(), "", "}", ",", true, 0)?;
348 entries.extend(tail);
349 Ok(Expr::Map { entries })
350 }
351
352 fn parse_sup(&mut self, head: Expr) -> ParseResult<Expr> {
353 let mut els = vec![head];
354 let tail = self.list_like(|p| p.parse_expr(false, false), "", "}", ",", true, 1)?;
355 els.extend(tail);
356 Ok(Expr::Sup { els })
357 }
358
359 fn parse_tree_node(&mut self) -> ParseResult<Expr> {
360 self.advance_one();
361 self.advance_one();
362 let left = self.parse_expr(false, false)?;
363 self.consume(",")?;
364 let right = self.parse_expr(false, false)?;
365 self.consume("]")?;
366 Ok(Expr::TreeNode { left: Box::new(left), right: Box::new(right) })
367 }
368
369 fn parse_tree_leaf(&mut self, inline: bool) -> ParseResult<Expr> {
370 self.advance_one();
371 let val = self.parse_expr(inline, false)?;
372 Ok(Expr::TreeLeaf { val: Box::new(val) })
373 }
374
375 fn data_kwarg(&mut self) -> ParseResult<(Name, Expr)> {
376 self.skip_trivia();
377 let nam = self.parse_var_name()?;
378 self.consume(":")?;
379 let expr = self.parse_expr(false, false)?;
380 Ok((nam, expr))
381 }
382
383 fn parse_map_entry(&mut self) -> ParseResult<(Expr, Expr)> {
384 let key = self.parse_expr(false, false)?;
385 self.consume(":")?;
386 let val = self.parse_expr(false, false)?;
387 Ok((key, val))
388 }
389
390 fn parse_list_or_comprehension(&mut self) -> ParseResult<Expr> {
391 self.consume_exactly("[")?;
392
393 self.skip_trivia();
395 if self.try_consume_exactly("]") {
396 return Ok(Expr::Lst { els: vec![] });
397 }
398
399 let head = self.parse_expr(false, false)?;
400 self.skip_trivia();
401 if self.try_parse_keyword("for") {
402 self.skip_trivia();
404 let bind = self.parse_var_name()?;
405 self.skip_trivia();
406 self.parse_keyword("in")?;
407 let iter = self.parse_expr(false, false)?;
408 let mut cond = None;
409 self.skip_trivia();
410 if self.try_parse_keyword("if") {
411 cond = Some(Box::new(self.parse_expr(false, false)?));
412 }
413 self.consume("]")?;
414 Ok(Expr::LstMap { term: Box::new(head), bind, iter: Box::new(iter), cond })
415 } else {
416 let mut head = vec![head];
418 self.skip_trivia();
419 if !self.starts_with("]") {
420 self.consume(",")?;
421 }
422 let tail = self.list_like(|p| p.parse_expr(false, false), "", "]", ",", true, 0)?;
423 head.extend(tail);
424 Ok(Expr::Lst { els: head })
425 }
426 }
427
428 fn parse_expr(&mut self, inline: bool, tup: bool) -> ParseResult<Expr> {
432 if inline {
433 self.skip_trivia_inline()?;
434 } else {
435 self.skip_trivia();
436 }
437
438 let base = self.parse_infix_expr(0, inline)?;
439 if !tup {
440 return Ok(base);
441 }
442 if inline {
443 self.skip_trivia_inline()?;
444 } else {
445 self.skip_trivia();
446 }
447 if self.starts_with(",") {
448 let mut els = vec![base];
449 loop {
450 if self.starts_with(",") {
451 self.advance_one();
452 els.push(self.parse_expr(inline, false)?);
453 if self.starts_with("\n") {
454 break;
455 }
456 if inline {
457 self.skip_trivia_inline()?;
458 } else {
459 self.skip_trivia();
460 }
461 } else {
462 break;
463 }
464 }
465 Ok(Expr::Tup { els })
466 } else {
467 Ok(base)
468 }
469 }
470
471 fn parse_named_arg(&mut self) -> ParseResult<(Option<Name>, Expr)> {
473 let arg = self.parse_expr(false, false)?;
474 if self.try_consume("=") {
475 if let Expr::Var { nam } = arg {
476 let bind = Some(nam);
477 let arg = self.parse_expr(false, false)?;
478 Ok((bind, arg))
479 } else {
480 let msg = "Unexpected '=' in unnamed argument.".to_string();
481 let idx = *self.index();
482 self.with_ctx(Err(msg), idx..idx + 1)
483 }
484 } else {
485 Ok((None, arg))
486 }
487 }
488
489 fn parse_infix_expr(&mut self, prec: usize, inline: bool) -> ParseResult<Expr> {
492 maybe_grow(|| {
493 if inline {
494 self.skip_trivia_inline()?;
495 } else {
496 self.skip_trivia();
497 }
498 if prec > Op::max_precedence() {
499 return self.call_or_postfix(inline);
500 }
501 let mut lhs = self.parse_infix_expr(prec + 1, inline)?;
502 if inline {
503 self.skip_trivia_inline()?;
504 } else {
505 self.skip_trivia();
506 }
507 while let Some(op) = self.peek_oper() {
508 if op.precedence() == prec {
509 self.try_parse_oper().unwrap();
510 let rhs = self.parse_infix_expr(prec + 1, inline)?;
511 lhs = Expr::Opr { op, lhs: Box::new(lhs), rhs: Box::new(rhs) };
512 self.skip_trivia_inline()?;
513 } else {
514 break;
515 }
516 }
517 Ok(lhs)
518 })
519 }
520
521 fn consume_indent_at_most(&mut self, expected: Indent) -> ParseResult<Indent> {
522 let got = self.advance_newlines()?;
523 match (expected, got) {
524 (_, Indent::Eof) => Ok(Indent::Eof),
525 (Indent::Val(expected), Indent::Val(got)) if got <= expected => Ok(Indent::Val(got)),
526 (expected, got) => self.expected_indent(expected, got),
527 }
528 }
529
530 fn consume_indent_exactly(&mut self, expected: Indent) -> ParseResult<()> {
531 let got = self.advance_newlines()?;
532 match (expected, got) {
533 (Indent::Eof, Indent::Eof) => Ok(()),
534 (Indent::Val(expected), Indent::Val(got)) if got == expected => Ok(()),
535 (expected, got) => self.expected_indent(expected, got),
536 }
537 }
538
539 fn parse_statement(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
541 maybe_grow(|| {
542 if self.starts_with_keyword("return") {
543 self.parse_return()
544 } else if self.starts_with_keyword("def") {
545 self.parse_local_def(indent)
546 } else if self.starts_with_keyword("if") {
547 self.parse_if(indent)
548 } else if self.starts_with_keyword("match") {
549 self.parse_match(indent)
550 } else if self.starts_with_keyword("switch") {
551 self.parse_switch(indent)
552 } else if self.starts_with_keyword("fold") {
553 self.parse_fold(indent)
554 } else if self.starts_with_keyword("bend") {
555 self.parse_bend(indent)
556 } else if self.starts_with_keyword("with") {
557 self.parse_with(indent)
558 } else if self.starts_with_keyword("open") {
559 self.parse_open(indent)
560 } else if self.starts_with_keyword("use") {
561 self.parse_use(indent)
562 } else {
563 self.parse_assign(indent)
564 }
565 })
566 }
567
568 fn parse_assign(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
573 let ini_idx = *self.index();
574 let pat = self.parse_assign_pattern()?;
575 let end_idx = *self.index();
576 self.skip_trivia_inline()?;
577
578 if self.starts_with("=") {
580 self.advance_one();
581 let val = self.parse_expr(true, true)?;
582 self.skip_trivia_inline()?;
583 self.try_consume_exactly(";");
584 if !self.is_eof() {
585 self.consume_new_line()?;
586 }
587 let nxt_indent = self.advance_newlines()?;
588 if nxt_indent == *indent {
589 let (nxt, nxt_indent) = self.parse_statement(indent)?;
590 let stmt = Stmt::Assign { pat, val: Box::new(val), nxt: Some(Box::new(nxt)) };
591 return Ok((stmt, nxt_indent));
592 } else {
593 let stmt = Stmt::Assign { pat, val: Box::new(val), nxt: None };
594 return Ok((stmt, nxt_indent));
595 }
596 }
597 if self.starts_with("<-") {
599 self.consume("<-")?;
600 let val = self.parse_expr(true, true)?;
601 self.skip_trivia_inline()?;
602 self.try_consume_exactly(";");
603 let nxt_indent = self.advance_newlines()?;
604 if nxt_indent == *indent {
605 let (nxt, nxt_indent) = self.parse_statement(indent)?;
606 let stmt = Stmt::Ask { pat, val: Box::new(val), nxt: Some(Box::new(nxt)) };
607 return Ok((stmt, nxt_indent));
608 } else {
609 let stmt = Stmt::Ask { pat, val: Box::new(val), nxt: None };
610 return Ok((stmt, nxt_indent));
611 }
612 }
613 match &pat {
616 AssignPattern::Var(..) => {}
617 AssignPattern::MapSet(..) => {}
618 _ => self.expected_spanned("Var or Map accessor", ini_idx..end_idx)?,
619 }
620 if let Some(op) = self.parse_in_place_op()? {
621 let val = self.parse_expr(true, false)?;
622 self.skip_trivia_inline()?;
623 self.try_consume_exactly(";");
624 self.consume_indent_exactly(*indent)?;
625 let (nxt, nxt_indent) = self.parse_statement(indent)?;
626 let stmt = Stmt::InPlace { op, pat: Box::new(pat), val: Box::new(val), nxt: Box::new(nxt) };
627 return Ok((stmt, nxt_indent));
628 }
629
630 self.expected_spanned("statement", ini_idx..end_idx)
631 }
632
633 fn parse_in_place_op(&mut self) -> ParseResult<Option<InPlaceOp>> {
634 self.skip_trivia_inline()?;
635 let op = if self.starts_with("+=") {
636 self.consume("+=")?;
637 Some(InPlaceOp::Add)
638 } else if self.starts_with("-=") {
639 self.consume("-=")?;
640 Some(InPlaceOp::Sub)
641 } else if self.starts_with("*=") {
642 self.consume("*=")?;
643 Some(InPlaceOp::Mul)
644 } else if self.starts_with("/=") {
645 self.consume("/=")?;
646 Some(InPlaceOp::Div)
647 } else if self.starts_with("&=") {
648 self.consume("&=")?;
649 Some(InPlaceOp::And)
650 } else if self.starts_with("|=") {
651 self.consume("|=")?;
652 Some(InPlaceOp::Or)
653 } else if self.starts_with("^=") {
654 self.consume("^=")?;
655 Some(InPlaceOp::Xor)
656 } else if self.starts_with("@=") {
657 self.consume("@=")?;
658 Some(InPlaceOp::Map)
659 } else {
660 None
661 };
662 Ok(op)
663 }
664
665 fn parse_return(&mut self) -> ParseResult<(Stmt, Indent)> {
666 self.parse_keyword("return")?;
667
668 let term = self.parse_expr(true, true)?;
669 self.skip_trivia_inline()?;
670
671 self.try_consume_exactly(";");
672 if !self.is_eof() {
673 self.consume_new_line()?;
674 }
675 let indent = self.advance_newlines()?;
676
677 Ok((Stmt::Return { term: Box::new(term) }, indent))
678 }
679
680 fn parse_if(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
681 self.parse_keyword("if")?;
682 self.skip_trivia_inline()?;
683
684 let cond = self.parse_expr(true, true)?;
685 self.skip_trivia_inline()?;
686 self.consume_exactly(":")?;
687 indent.enter_level();
688
689 self.consume_indent_exactly(*indent)?;
690 let (then, nxt_indent) = self.parse_statement(indent)?;
691 indent.exit_level();
692
693 if nxt_indent != *indent {
694 return self
695 .expected_indent(*indent, nxt_indent)
696 .or(self.expected_spanned("'else' or 'elif'", self.index..self.index + 1));
697 }
698 let mut elifs = Vec::new();
699 while self.try_parse_keyword("elif") {
700 let cond = self.parse_expr(true, false)?;
701 self.skip_trivia_inline()?;
702 self.consume_exactly(":")?;
703 indent.enter_level();
704 self.consume_indent_exactly(*indent)?;
705 let (then, nxt_indent) = self.parse_statement(indent)?;
706 indent.exit_level();
707
708 if nxt_indent != *indent {
709 return self
710 .expected_indent(*indent, nxt_indent)
711 .or(self.expected_spanned("'else' or 'elif'", self.index..self.index + 1));
712 }
713 elifs.push((cond, then));
714 }
715 self.parse_keyword("else")?;
716 self.skip_trivia_inline()?;
717 self.consume_exactly(":")?;
718 indent.enter_level();
719
720 self.consume_indent_exactly(*indent)?;
721 let (otherwise, nxt_indent) = self.parse_statement(indent)?;
722 let otherwise = elifs.into_iter().rfold(otherwise, |acc, (cond, then)| Stmt::If {
723 cond: Box::new(cond),
724 then: Box::new(then),
725 otherwise: Box::new(acc),
726 nxt: None,
727 });
728
729 indent.exit_level();
730 if nxt_indent == *indent {
731 let (nxt, nxt_indent) = self.parse_statement(indent)?;
732 let stmt = Stmt::If {
733 cond: Box::new(cond),
734 then: Box::new(then),
735 otherwise: Box::new(otherwise),
736 nxt: Some(Box::new(nxt)),
737 };
738 Ok((stmt, nxt_indent))
739 } else {
740 let stmt =
741 Stmt::If { cond: Box::new(cond), then: Box::new(then), otherwise: Box::new(otherwise), nxt: None };
742 Ok((stmt, nxt_indent))
743 }
744 }
745
746 fn parse_match(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
747 self.parse_keyword("match")?;
748 self.skip_trivia_inline()?;
749
750 let (bnd, arg) = self.parse_match_arg()?;
751 self.skip_trivia_inline()?;
752
753 let (with_bnd, with_arg) = self.parse_with_clause()?;
754 self.consume_new_line()?;
755 indent.enter_level();
756
757 self.consume_indent_exactly(*indent).or(self.expected_spanned("'case'", self.index..self.index + 1))?;
758 let (case, mut nxt_indent) = self.parse_match_case(indent)?;
759 let mut arms = vec![case];
760 while nxt_indent == *indent {
761 let (case, nxt_indent_) = self.parse_match_case(indent)?;
762 nxt_indent = nxt_indent_;
763 arms.push(case);
764 }
765 indent.exit_level();
766 if nxt_indent == *indent {
767 let (nxt, nxt_indent) = self.parse_statement(indent)?;
768 let stmt = Stmt::Match { arg: Box::new(arg), bnd, with_bnd, with_arg, arms, nxt: Some(Box::new(nxt)) };
769 Ok((stmt, nxt_indent))
770 } else {
771 let stmt = Stmt::Match { arg: Box::new(arg), bnd, with_bnd, with_arg, arms, nxt: None };
772 Ok((stmt, nxt_indent))
773 }
774 }
775
776 fn parse_match_arg(&mut self) -> ParseResult<(Option<Name>, Expr)> {
777 let ini_idx = *self.index();
778 let arg = self.parse_expr(true, false)?;
779 let end_idx = *self.index();
780
781 self.skip_trivia_inline()?;
782 match (arg, self.starts_with("=")) {
783 (Expr::Var { nam }, true) => {
784 self.advance_one();
785 Ok((Some(nam), self.parse_expr(true, false)?))
786 }
787 (_, true) => self.expected_spanned("argument name", ini_idx..end_idx),
788 (Expr::Var { nam }, false) => Ok((Some(nam.clone()), Expr::Var { nam })),
789 (arg, false) => Ok((Some(Name::new("%arg")), arg)),
790 }
791 }
792
793 fn parse_with_clause(&mut self) -> ParseResult<(Vec<Option<Name>>, Vec<Expr>)> {
794 self.skip_trivia_inline()?;
795 let res = if self.try_parse_keyword("with") {
796 self.list_like(|p| p.parse_with_arg(), "", ":", ",", true, 1)?.into_iter().unzip()
797 } else {
798 self.consume_exactly(":")?;
799 (vec![], vec![])
800 };
801 Ok(res)
802 }
803
804 fn parse_with_arg(&mut self) -> ParseResult<(Option<Name>, Expr)> {
805 let bind = self.parse_var_name()?;
806 self.skip_trivia_inline()?;
807 if self.try_consume("=") {
808 let arg = self.parse_expr(false, false)?;
809 Ok((Some(bind), arg))
810 } else {
811 Ok((Some(bind.clone()), Expr::Var { nam: bind }))
812 }
813 }
814
815 fn parse_match_case(&mut self, indent: &mut Indent) -> ParseResult<(MatchArm, Indent)> {
816 self.parse_keyword("case")?;
817 self.skip_trivia_inline()?;
818 let pat = if self.try_consume_exactly("_") {
819 None
820 } else {
821 let nam = self.labelled(|p| p.parse_var_name(), "name or '_'")?;
822 Some(nam)
823 };
824 self.skip_trivia_inline()?;
825 self.consume_exactly(":")?;
826 self.consume_new_line()?;
827 indent.enter_level();
828
829 self.consume_indent_exactly(*indent)?;
830 let (body, nxt_indent) = self.parse_statement(indent)?;
831 indent.exit_level();
832
833 let stmt = MatchArm { lft: pat, rgt: body };
834 Ok((stmt, nxt_indent))
835 }
836
837 fn parse_switch(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
838 self.parse_keyword("switch")?;
839 self.skip_trivia_inline()?;
840
841 let (bnd, arg) = self.parse_match_arg()?;
842 self.skip_trivia_inline()?;
843
844 let (with_bnd, with_arg) = self.parse_with_clause()?;
845 indent.enter_level();
846
847 self.consume_indent_exactly(*indent)?;
848 let ini_idx = *self.index();
849 let (fst_case, fst_stmt, mut nxt_indent) = self.parse_switch_case(indent)?;
850 let end_idx = *self.index();
851 if fst_case != Some(0) {
852 return self.expected_spanned("case 0", ini_idx..end_idx);
853 }
854 let mut arms = vec![fst_stmt];
855 let mut should_continue = fst_case == Some(0);
856 let mut expected_num = 1;
857 while should_continue {
858 if nxt_indent != *indent {
859 return self
860 .expected_indent(*indent, nxt_indent)
861 .or(self.expected_spanned("'case'", self.index..self.index + 1));
862 }
863 let (case, stmt, nxt_indent_) = self.parse_switch_case(indent)?;
864 nxt_indent = nxt_indent_;
865 if let Some(case) = case {
866 if case != expected_num {
867 return self.expected(&format!("case {}", expected_num));
868 }
869 should_continue = true;
870 arms.push(stmt);
871 expected_num += 1;
872 } else {
873 should_continue = false;
874 arms.push(stmt);
875 }
876 }
877 indent.exit_level();
878 if nxt_indent == *indent {
879 let (nxt, nxt_indent) = self.parse_statement(indent)?;
880 let stmt = Stmt::Switch { arg: Box::new(arg), bnd, with_bnd, with_arg, arms, nxt: Some(Box::new(nxt)) };
881 Ok((stmt, nxt_indent))
882 } else {
883 let stmt = Stmt::Switch { arg: Box::new(arg), bnd, with_bnd, with_arg, arms, nxt: None };
884 Ok((stmt, nxt_indent))
885 }
886 }
887
888 fn parse_switch_case(&mut self, indent: &mut Indent) -> ParseResult<(Option<u32>, Stmt, Indent)> {
889 self.parse_keyword("case")?;
890 self.skip_trivia_inline()?;
891 let case = if let Some(c) = self.peek_one() {
892 match c {
893 '_' => {
894 self.advance_one();
895 None
896 }
897 c if c.is_ascii_digit() => Some(self.parse_u32()?),
898 _ => return self.expected("number or '_'"),
899 }
900 } else {
901 return self.expected("number or '_'")?;
902 };
903
904 self.skip_trivia_inline()?;
905 self.consume_exactly(":")?;
906 self.consume_new_line()?;
907 indent.enter_level();
908 self.consume_indent_exactly(*indent)?;
909 let (stmt, nxt_indent) = self.parse_statement(indent)?;
910 indent.exit_level();
911 Ok((case, stmt, nxt_indent))
912 }
913
914 fn parse_fold(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
919 self.parse_keyword("fold")?;
920 self.skip_trivia_inline()?;
921
922 let (bind, arg) = self.parse_match_arg()?;
924 self.skip_trivia_inline()?;
925
926 let (with_bnd, with_arg) = self.parse_with_clause()?;
927 self.consume_new_line()?;
928 indent.enter_level();
929
930 self.consume_indent_exactly(*indent).or(self.expected_spanned("'case'", self.index..self.index + 1))?;
931 let (case, mut nxt_indent) = self.parse_match_case(indent)?;
932 let mut arms = vec![case];
933 while nxt_indent == *indent {
934 let (case, nxt_indent_) = self.parse_match_case(indent)?;
935 nxt_indent = nxt_indent_;
936 arms.push(case);
937 }
938 indent.exit_level();
939 if nxt_indent == *indent {
940 let (nxt, nxt_indent) = self.parse_statement(indent)?;
941 let stmt =
942 Stmt::Fold { arg: Box::new(arg), bnd: bind, arms, with_bnd, with_arg, nxt: Some(Box::new(nxt)) };
943 Ok((stmt, nxt_indent))
944 } else {
945 let stmt = Stmt::Fold { arg: Box::new(arg), bnd: bind, arms, with_bnd, with_arg, nxt: None };
946 Ok((stmt, nxt_indent))
947 }
948 }
949
950 fn parse_bend(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
956 self.parse_keyword("bend")?;
957 self.skip_trivia_inline()?;
958
959 let args = self.list_like(|p| p.parse_match_arg(), "", ":", ",", true, 1)?;
960 let (bind, init) = args.into_iter().unzip();
961 self.consume_new_line()?;
962 indent.enter_level();
963
964 self.consume_indent_exactly(*indent).or(self.expected_spanned("'when'", self.index..self.index + 1))?;
965 self.parse_keyword("when")?;
966 self.skip_trivia_inline()?;
967
968 let cond = self.parse_expr(true, true)?;
969 self.skip_trivia_inline()?;
970
971 self.consume_exactly(":")?;
972 self.consume_new_line()?;
973 indent.enter_level();
974
975 self.consume_indent_exactly(*indent)?;
976 let (step, nxt_indent) = self.parse_statement(indent)?;
977 indent.exit_level();
978
979 if nxt_indent != *indent {
980 return self
981 .expected_indent(*indent, nxt_indent)
982 .or(self.expected_spanned("'else'", self.index..self.index + 1));
983 }
984 self.parse_keyword("else")?;
985 self.skip_trivia_inline()?;
986 self.consume_exactly(":")?;
987 self.consume_new_line()?;
988 indent.enter_level();
989
990 self.consume_indent_exactly(*indent)?;
991 let (base, nxt_indent) = self.parse_statement(indent)?;
992 indent.exit_level();
993
994 indent.exit_level();
995 if nxt_indent == *indent {
996 let (nxt, nxt_indent) = self.parse_statement(indent)?;
997 let stmt = Stmt::Bend {
998 bnd: bind,
999 arg: init,
1000 cond: Box::new(cond),
1001 step: Box::new(step),
1002 base: Box::new(base),
1003 nxt: Some(Box::new(nxt)),
1004 };
1005 Ok((stmt, nxt_indent))
1006 } else {
1007 let stmt = Stmt::Bend {
1008 bnd: bind,
1009 arg: init,
1010 cond: Box::new(cond),
1011 step: Box::new(step),
1012 base: Box::new(base),
1013 nxt: None,
1014 };
1015 Ok((stmt, nxt_indent))
1016 }
1017 }
1018
1019 fn parse_with(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
1023 self.parse_keyword("with")?;
1024 self.skip_trivia_inline()?;
1025
1026 let typ = self.parse_var_name()?;
1027 self.skip_trivia_inline()?;
1028
1029 self.consume_exactly(":")?;
1030 self.consume_new_line()?;
1031 indent.enter_level();
1032
1033 self.consume_indent_exactly(*indent)?;
1034 let (bod, nxt_indent) = self.parse_statement(indent)?;
1035 indent.exit_level();
1036
1037 if nxt_indent == *indent {
1038 let (nxt, nxt_indent) = self.parse_statement(indent)?;
1039 let stmt = Stmt::With { typ, bod: Box::new(bod), nxt: Some(Box::new(nxt)) };
1040 Ok((stmt, nxt_indent))
1041 } else {
1042 let stmt = Stmt::With { typ, bod: Box::new(bod), nxt: None };
1043 Ok((stmt, nxt_indent))
1044 }
1045 }
1046
1047 fn parse_assign_pattern(&mut self) -> ParseResult<AssignPattern> {
1051 let head_ini = *self.index();
1052 let head = self.parse_primary_assign_pattern()?;
1053 let head_end = *self.index();
1054 self.skip_trivia_inline()?;
1055 if self.starts_with("[") {
1056 self.advance_one();
1058 let key = self.parse_expr(false, false)?;
1059 self.consume("]")?;
1060 if let AssignPattern::Var(var) = head {
1061 Ok(AssignPattern::MapSet(var, key))
1062 } else {
1063 self.with_ctx(Err("Expected a variable pattern"), head_ini..head_end)
1064 }
1065 } else if self.starts_with(",") {
1066 let mut els = vec![head];
1067 while self.try_consume(",") {
1068 self.skip_trivia_inline()?;
1069 els.push(self.parse_primary_assign_pattern()?);
1070 }
1071 Ok(AssignPattern::Tup(els))
1072 } else {
1073 Ok(head)
1074 }
1075 }
1076
1077 fn parse_primary_assign_pattern(&mut self) -> ParseResult<AssignPattern> {
1083 if self.starts_with("*") {
1084 self.advance_one();
1085 Ok(AssignPattern::Eraser)
1086 } else if self.starts_with("{") {
1087 let binds = self.list_like(|p| p.parse_primary_assign_pattern(), "{", "}", ",", true, 2)?;
1088 Ok(AssignPattern::Sup(binds))
1089 } else if self.starts_with("$") {
1090 self.advance_one();
1091 self.skip_trivia_inline()?;
1092 let nam = self.parse_var_name()?;
1093 Ok(AssignPattern::Chn(nam))
1094 } else if self.starts_with("(") {
1095 self.advance_one();
1096 let assign = self.parse_assign_pattern()?;
1097 self.consume(")")?;
1098 Ok(assign)
1099 } else {
1100 Ok(AssignPattern::Var(self.parse_var_name()?))
1101 }
1102 }
1103
1104 fn parse_open(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
1106 self.parse_keyword("open")?;
1107 self.skip_trivia_inline()?;
1108
1109 let typ = self.labelled(|p| p.parse_var_name(), "type name")?;
1110 self.skip_trivia_inline()?;
1111
1112 self.consume_exactly(":")?;
1113 self.skip_trivia_inline()?;
1114
1115 let var = self.labelled(|p| p.parse_var_name(), "variable name")?;
1116 self.skip_trivia_inline()?;
1117
1118 self.try_consume_exactly(";");
1119 self.consume_new_line()?;
1120 self.consume_indent_exactly(*indent)?;
1121
1122 let (nxt, nxt_indent) = self.parse_statement(indent)?;
1123
1124 let stmt = Stmt::Open { typ, var, nxt: Box::new(nxt) };
1125 Ok((stmt, nxt_indent))
1126 }
1127
1128 fn parse_use(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
1129 self.parse_keyword("use")?;
1130 self.skip_trivia_inline()?;
1131
1132 let nam = self.parse_var_name()?;
1133 self.skip_trivia_inline()?;
1134
1135 self.consume_exactly("=")?;
1136 self.skip_trivia_inline()?;
1137
1138 let bod = self.parse_expr(true, true)?;
1139 self.skip_trivia_inline()?;
1140
1141 self.try_consume_exactly(";");
1142 self.consume_new_line()?;
1143 self.consume_indent_exactly(*indent)?;
1144
1145 let (nxt, nxt_indent) = self.parse_statement(indent)?;
1146
1147 let stmt = Stmt::Use { nam, val: Box::new(bod), nxt: Box::new(nxt) };
1148 Ok((stmt, nxt_indent))
1149 }
1150
1151 fn parse_local_def(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
1152 let (mut def, mut nxt_indent) = self.parse_def_aux(*indent)?;
1154 def.source.kind = if self.builtin { SourceKind::Builtin } else { SourceKind::Generated };
1155 let (nxt, nxt_indent) = self.parse_statement(&mut nxt_indent)?;
1156 let stmt = Stmt::LocalDef { def: Box::new(def), nxt: Box::new(nxt) };
1157 Ok((stmt, nxt_indent))
1158 }
1159
1160 fn parse_type_expr(&mut self) -> ParseResult<Type> {
1162 maybe_grow(|| {
1165 self.skip_trivia_inline()?;
1166 let ini_idx = *self.index();
1167 let lft = if self.try_parse_keyword("Any") {
1168 Type::Any
1169 } else if self.try_parse_keyword("None") {
1170 Type::None
1171 } else if self.try_parse_keyword("_") {
1172 Type::Hole
1173 } else if self.try_parse_keyword("u24") {
1174 Type::U24
1175 } else if self.try_parse_keyword("i24") {
1176 Type::I24
1177 } else if self.try_parse_keyword("f24") {
1178 Type::F24
1179 } else if self.try_consume_exactly("(") {
1180 self.skip_trivia();
1182 let head = self.parse_type_expr()?;
1183 self.skip_trivia();
1184 if self.try_consume_exactly(")") {
1185 head
1187 } else if self.starts_with(",") {
1188 let mut types = vec![head];
1190 loop {
1191 self.consume_exactly(",")?;
1192 types.push(self.parse_type_expr()?);
1193 if self.try_consume_exactly(")") {
1194 break;
1195 }
1196 if !self.starts_with(",") {
1197 return self.expected("',' or ')'");
1198 }
1199 }
1200 Type::Tup(types)
1201 } else {
1202 let end_idx = *self.index();
1203 return self.expected_spanned("tuple type or parenthesized type", ini_idx..end_idx);
1204 }
1205 } else {
1206 let name = self.parse_var_name()?;
1209 self.skip_trivia_inline()?;
1210 if self.try_consume_exactly("(") {
1211 let args = self.list_like(|p| p.parse_type_expr(), "", ")", ",", true, 0)?;
1215 Type::Ctr(name, args)
1216 } else {
1217 Type::Var(name)
1219 }
1220 };
1221
1222 self.skip_trivia_inline()?;
1224 if self.try_consume_exactly("->") {
1225 let rgt = self.parse_type_expr()?;
1226 Ok(Type::Arr(Box::new(lft), Box::new(rgt)))
1227 } else {
1228 Ok(lft)
1229 }
1230 })
1231 }
1232
1233 fn parse_def_aux(&mut self, mut indent: Indent) -> ParseResult<(Definition, Indent)> {
1234 let ini_idx = *self.index();
1235 self.parse_keyword("def")?;
1236 self.skip_trivia_inline()?;
1237
1238 let check = if self.try_parse_keyword("unchecked") {
1239 (false, true)
1240 } else if self.try_parse_keyword("checked") {
1241 (true, false)
1242 } else {
1243 (false, false)
1244 };
1245 self.skip_trivia_inline()?;
1246
1247 let name = self.parse_top_level_name()?;
1248 self.skip_trivia_inline()?;
1249
1250 let args = if self.try_consume_exactly("(") {
1251 self.list_like(|p| p.parse_def_arg(), "", ")", ",", true, 0)?
1252 } else {
1253 vec![]
1254 };
1255 self.skip_trivia_inline()?;
1256 let (args, arg_types): (Vec<_>, Vec<_>) = args.into_iter().unzip();
1257
1258 let ret_type = self.parse_return_type()?;
1259 self.skip_trivia_inline()?;
1260
1261 self.consume_exactly(":")?;
1262 self.consume_new_line()?;
1263 indent.enter_level();
1264 self.consume_indent_exactly(indent)?;
1265
1266 let (body, nxt_indent) = self.parse_statement(&mut indent)?;
1267 indent.exit_level();
1268
1269 let check = if check.0 {
1271 true
1272 } else if check.1 {
1273 false
1274 } else {
1275 ret_type.is_some() || arg_types.iter().any(|t| t.is_some())
1276 };
1277 let arg_types = arg_types.into_iter().map(|t| t.unwrap_or(Type::Any)).collect::<Vec<_>>();
1278 let typ = make_fn_type(arg_types, ret_type.unwrap_or(Type::Any));
1279
1280 let source = Source::from_file_span(&self.file, self.input, ini_idx..self.index, self.builtin);
1282 let def = Definition { name, args, typ, check, body, source };
1283 Ok((def, nxt_indent))
1284 }
1285
1286 fn parse_def_arg(&mut self) -> ParseResult<(Name, Option<Type>)> {
1287 let name = self.parse_var_name()?;
1288 self.skip_trivia_inline()?;
1289 if self.try_consume_exactly(":") {
1290 let typ = self.parse_type_expr()?;
1291 Ok((name, Some(typ)))
1292 } else {
1293 Ok((name, None))
1294 }
1295 }
1296
1297 fn parse_return_type(&mut self) -> ParseResult<Option<Type>> {
1298 if self.try_consume_exactly("->") {
1299 Ok(Some(self.parse_type_expr()?))
1300 } else {
1301 Ok(None)
1302 }
1303 }
1304
1305 fn expected_indent<T>(&mut self, expected: Indent, got: Indent) -> ParseResult<T> {
1306 match (expected, got) {
1307 (Indent::Eof, Indent::Eof) => unreachable!(),
1308 (Indent::Eof, Indent::Val(got)) => {
1309 let msg = format!("Indentation error. Expected end-of-input, got {} spaces.", got);
1310 let idx = *self.index();
1311 self.with_ctx(Err(msg), idx..idx + 1)
1312 }
1313 (Indent::Val(expected), Indent::Eof) => {
1314 let msg = format!("Indentation error. Expected {} spaces, got end-of-input.", expected);
1315 let idx = *self.index();
1316 self.with_ctx(Err(msg), idx..idx + 1)
1317 }
1318 (Indent::Val(expected), Indent::Val(got)) => {
1319 if got != expected {
1320 let msg = format!("Indentation error. Expected {} spaces, got {}.", expected, got);
1321 let idx = *self.index();
1322 self.with_ctx(Err(msg), idx..idx + 1)
1323 } else {
1324 unreachable!()
1325 }
1326 }
1327 }
1328 }
1329}
1330
1331impl<'a> ParserCommons<'a> for ImpParser<'a> {}
1332
1333impl<'a> Parser<'a> for ImpParser<'a> {
1334 fn input(&mut self) -> &'a str {
1335 self.input
1336 }
1337
1338 fn index(&mut self) -> &mut usize {
1339 &mut self.index
1340 }
1341
1342 fn expected<T>(&mut self, exp: &str) -> ParseResult<T> {
1346 let ini_idx = *self.index();
1347 let end_idx = *self.index() + 1;
1348 self.expected_spanned(exp, ini_idx..end_idx)
1349 }
1350
1351 fn consume(&mut self, text: &str) -> ParseResult<()> {
1355 self.skip_trivia();
1356 if self.input().get(*self.index()..).unwrap_or_default().starts_with(text) {
1357 *self.index() += text.len();
1358 Ok(())
1359 } else {
1360 self.expected(format!("'{text}'").as_str())
1361 }
1362 }
1363
1364 fn skip_trivia(&mut self) {
1365 while let Some(c) = self.peek_one() {
1366 if c.is_ascii_whitespace() {
1367 self.advance_one();
1368 continue;
1369 }
1370 if c == '#' {
1371 while let Some(c) = self.peek_one() {
1372 if c != '\n' {
1373 self.advance_one();
1374 } else {
1375 break;
1376 }
1377 }
1378 self.advance_one(); continue;
1380 }
1381 break;
1382 }
1383 }
1384}
1385
1386impl Op {
1387 fn precedence(&self) -> usize {
1388 match self {
1389 Op::OR => 0,
1390 Op::XOR => 1,
1391 Op::AND => 2,
1392 Op::EQ => 3,
1393 Op::NEQ => 3,
1394 Op::LT => 4,
1395 Op::GT => 4,
1396 Op::LE => 4,
1397 Op::GE => 4,
1398 Op::SHL => 5,
1399 Op::SHR => 5,
1400 Op::ADD => 6,
1401 Op::SUB => 6,
1402 Op::MUL => 7,
1403 Op::DIV => 7,
1404 Op::REM => 7,
1405 Op::POW => 8,
1406 }
1407 }
1408
1409 fn max_precedence() -> usize {
1410 8
1411 }
1412}